FINAL suepr merge step : added all modules to this super repos

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-19 16:46:59 +02:00
7585 changed files with 1723356 additions and 18 deletions

View File

@@ -0,0 +1,16 @@
This folder includes files that can be used to test imports of date information.
To test them, set up FeedAPI and the Feed Element Mapper with Parser iCal
or Parser CVS and import these files into a date field.
- rrule.ics:
Creates repeating dates using a wide variety of RRULEs.
- Yahoo.csv:
This file uses the csv export format from Yahoo Calendar, similar to the
format created by Outlook's csv export. The sample contains both timed
and untimed 'All day' events.
- USHolidays.ics:
An ical export of US Holidays in the 'All day' format used by
Microsoft and Apple (where the Start date is the date of the event
and the End date is the following day).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
"Subject","Start Date","Start Time","End Date","End Time","All day event","Description"
"New Year's Day","1/1/2009","","","","true",""
"Valentine's Day","2/14/2009","","","","true",""
"St. Patrick's Day","3/17/2009","","","","true",""
"Memorial Day","5/31/2009","","","","true",""
"Independence Day","7/4/2009","","","","true",""
"Labor Day","09/07/2009","","","","true",""
"Halloween","10/31/2009","","","","true",""
"Veteran's Day","11/11/2009","","","","true",""
"Thanksgiving Day","11/26/2009","","","","true",""
"Christmas Day","12/25/2009","","","","true",""
"Do It With Drupal","12/10/2008","08:00 AM","12/10/2008","05:00 PM","false",""
"DrupalCon","03/04/2009","08:00 AM","03/04/2009","05:00 PM","false",""
"DrupalCon","03/05/2009","08:00 AM","03/05/2009","05:00 PM","false",""
"DrupalCon","03/06/2009","08:00 AM","03/06/2009","05:00 PM","false",""
"DrupalCon","03/07/2009","08:00 AM","03/07/2009","05:00 PM","false",""
1 Subject Start Date Start Time End Date End Time All day event Description
2 New Year's Day 1/1/2009 true
3 Valentine's Day 2/14/2009 true
4 St. Patrick's Day 3/17/2009 true
5 Memorial Day 5/31/2009 true
6 Independence Day 7/4/2009 true
7 Labor Day 09/07/2009 true
8 Halloween 10/31/2009 true
9 Veteran's Day 11/11/2009 true
10 Thanksgiving Day 11/26/2009 true
11 Christmas Day 12/25/2009 true
12 Do It With Drupal 12/10/2008 08:00 AM 12/10/2008 05:00 PM false
13 DrupalCon 03/04/2009 08:00 AM 03/04/2009 05:00 PM false
14 DrupalCon 03/05/2009 08:00 AM 03/05/2009 05:00 PM false
15 DrupalCon 03/06/2009 08:00 AM 03/06/2009 05:00 PM false
16 DrupalCon 03/07/2009 08:00 AM 03/07/2009 05:00 PM false

View File

@@ -0,0 +1,168 @@
<?php
/**
* @file
* Test date UI.
*/
class DateUITestCase extends DrupalWebTestCase {
protected $privileged_user;
/**
* @todo.
*/
public static function getInfo() {
return array(
'name' => 'Field UI',
'description' => 'Test creation of various date fields and widgets using Field UI.',
'group' => 'Date',
);
}
/**
* @todo.
*/
public function setUp() {
// Load the date_api module.
parent::setUp('field', 'field_ui', 'date_api', 'date', 'date_popup', 'date_tools');
// Create and log in our privileged user.
$this->privileged_user = $this->drupalCreateUser(
array('administer content types', 'administer nodes', 'bypass node access', 'administer date tools')
);
$this->drupalLogin($this->privileged_user);
variable_set('date_format_long', 'D, m/d/Y - H:i');
}
/**
* @todo.
*/
public function testFieldUI() {
$edit = array();
$edit['name'] = 'Story';
$edit['type'] = 'story';
$this->drupalPost('admin/structure/types/add', $edit, t('Save content type'));
$this->assertText('The content type Story has been added.', 'Content type added.');
// Creates select list field stored as a date with default settings.
$this->createDateField($type = 'date', $widget = 'date_select');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'select');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a date field using the date_select widget.');
$this->deleteDateField();
// Creates text field stored as a date with default settings.
$this->createDateField($type = 'date', $widget = 'date_text');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'text');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a date field using the date_text widget.');
$this->deleteDateField();
// Creates popup field stored as a date with default settings.
$this->createDateField($type = 'date', $widget = 'date_popup');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'popup');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a date field using the date_popup widget.');
$this->deleteDateField();
// Creates select list field stored as a datestamp with default settings.
$this->createDateField($type = 'datestamp', $widget = 'date_select');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'select');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a datestamp field using the date_select widget.');
$this->deleteDateField();
// Creates text field stored as a datestamp with default settings.
$this->createDateField($type = 'datestamp', $widget = 'date_text');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'text');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a datestamp field using the date_text widget.');
$this->deleteDateField();
// Creates popup field stored as a datestamp with default settings.
$this->createDateField($type = 'datestamp', $widget = 'date_popup');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'popup');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a datestamp field using the date_popup widget.');
$this->deleteDateField();
// Creates select list field stored as a datetime with default settings.
$this->createDateField($type = 'datetime', $widget = 'date_select');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'select');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a datetime field using the date_select widget.');
$this->deleteDateField();
// Creates text field stored as a datetime with default settings.
$this->createDateField($type = 'datetime', $widget = 'date_text');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'text');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a datetime field using the date_text widget.');
$this->deleteDateField();
// Creates popup field stored as a datetime with default settings.
$this->createDateField($type = 'datetime', $widget = 'date_popup');
$edit = array();
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->dateForm($options = 'popup');
$this->assertText('Thu, 10/07/2010 - 10:30', 'Found the correct date for a datetime field using the date_popup widget.');
$this->deleteDateField();
// Test timezone handling validation on the field settings form.
$this->createDateField($type = 'date', $widget = 'date_select');
$edit = array('field[settings][granularity][hour]' => FALSE);
$this->drupalPost(NULL, $edit, t('Save field settings'));
$this->assertText("Dates without hours granularity must not use any timezone handling.", "Dates without hours granularity required to use timezone handling of 'none.'");
$this->deleteDateField();
}
/**
* @todo.
*/
function dateForm($options) {
// Tests that date field functions properly.
$edit = array();
$edit['title'] = $this->randomName(8);
$edit['body[und][0][value]'] = $this->randomName(16);
if ($options == 'select') {
$edit['field_test[und][0][value][year]'] = '2010';
$edit['field_test[und][0][value][month]'] = '10';
$edit['field_test[und][0][value][day]'] = '7';
$edit['field_test[und][0][value][hour]'] = '10';
$edit['field_test[und][0][value][minute]'] = '30';
}
elseif ($options == 'text') {
$edit['field_test[und][0][value][date]'] = '10/07/2010 - 10:30';
}
elseif ($options == 'popup') {
$edit['field_test[und][0][value][date]'] = '10/07/2010';
$edit['field_test[und][0][value][time]'] = '10:30';
}
$this->drupalPost('node/add/story', $edit, t('Save'));
$this->assertText($edit['body[und][0][value]'], 'Test node has been created');
}
/**
* @todo.
*/
function createDateField($type, $widget) {
$edit = array();
$edit['fields[_add_new_field][label]'] = 'Test';
$edit['fields[_add_new_field][field_name]'] = 'test';
$edit['fields[_add_new_field][weight]'] = '-4';
$edit['fields[_add_new_field][type]'] = $type;
$edit['fields[_add_new_field][widget_type]'] = $widget;
$this->drupalPost('admin/structure/types/manage/story/fields', $edit, t('Save'));
}
/**
* @todo.
*/
function deleteDateField() {
$this->drupalGet('admin/structure/types/manage/story/fields');
$this->clickLink('delete');
$this->drupalPost(NULL, NULL, t('Delete'));
$this->assertText('The field Test has been deleted from the Story content type.', 'Removed date field.');
}
}

View File

@@ -0,0 +1,409 @@
<?php
/**
* @file
* Test Date API functions
*/
class DateAPITestCase extends DrupalWebTestCase {
/**
* @todo.
*/
public static function getInfo() {
return array(
'name' => t('Date API'),
'description' => t('Test Date API functions.') ,
'group' => t('Date'),
);
}
/**
* @todo.
*/
public function setUp() {
// Load the date_api module.
parent::setUp('date_api');
variable_set('date_api_use_iso8601', FALSE);
variable_set('date_first_day', 1);
}
/**
* @todo.
*/
public function testDateAPI() {
// Test date_format_date().
$formatters = array(
'a',
'A',
'B',
'c',
'd',
'D',
'e',
'F',
'g',
'G',
'h',
'H',
'i',
'I',
'j',
'l',
'L',
'm',
'M',
'n',
'N',
'o',
'O',
'P',
'r',
'R',
's',
'S',
't',
'T',
'u',
'U',
'w',
'W',
'y',
'Y',
'z',
'Z',
);
foreach ($formatters as $formatter) {
$date_api_format = date_format_date(date_now(), 'custom', $formatter);
$php_format = date_format(date_now(), $formatter);
$this->assertEqual($date_api_format, $php_format, 'Test that the "' . $formatter . '" formatter is formatted correctly by date_format_date()');
}
// Test the order of the weeks days for a calendar that starts on Monday and
// one that starts on Sunday.
variable_set('date_first_day', 1);
$expected = array(0 => t('Mon'), 1 => t('Tue'), 2 => t('Wed'), 3 => t('Thu'), 4 => t('Fri'), 5 => t('Sat'), 6 => t('Sun'));
$days = date_week_days_ordered(date_week_days_abbr(1));
$this->assertEqual($expected, $days, 'Test that date_week_days_ordered() array starts on Monday when the site first day is on Monday.');
variable_set('date_first_day', 0);
$expected = array(0 => t('Sun'), 1 => t('Mon'), 2 => t('Tue'), 3 => t('Wed'), 4 => t('Thu'), 5 => t('Fri'), 6 => t('Sat'));
$days = date_week_days_ordered(date_week_days_abbr(1));
$this->assertEqual($expected, $days, 'Test that date_week_days_ordered() array starts on Sunday when the site first day is on Sunday.');
// Test days in February for a leap year and a non-leap year.
$expected = 28;
$value = date_days_in_month(2005, 2);
$this->assertEqual($expected, $value, "Test date_days_in_month(2, 2005): should be $expected, found $value.");
$expected = 29;
$value = date_days_in_month(2004, 2);
$this->assertEqual($expected, $value, "Test date_days_in_month(2, 2004): should be $expected, found $value.");
// Test days in year for a leap year and a non-leap year.
$expected = 365;
$value = date_days_in_year('2005-06-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_days_in_year(2005-06-01): should be $expected, found $value.");
$expected = 366;
$value = date_days_in_year('2004-06-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_days_in_year(2004-06-01): should be $expected, found $value.");
// Test ISO weeks for a leap year and a non-leap year.
$expected = 52;
$value = date_iso_weeks_in_year('2008-06-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_iso_weeks_in_year(2008-06-01): should be $expected, found $value.");
$expected = 53;
$value = date_iso_weeks_in_year('2009-06-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_iso_weeks_in_year(2009-06-01): should be $expected, found $value.");
// Test day of week for March 1, the day after leap day.
$expected = 6;
$value = date_day_of_week('2008-03-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_day_of_week(2008-03-01): should be $expected, found $value.");
$expected = 0;
$value = date_day_of_week('2009-03-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_day_of_week(2009-03-01): should be $expected, found $value.");
// Test day of week name for March 1, the day after leap day.
$expected = 'Sat';
$value = date_day_of_week_name('2008-03-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_day_of_week_name(2008-03-01): should be $expected, found $value.");
$expected = 'Sun';
$value = date_day_of_week_name('2009-03-01 00:00:00');
$this->assertEqual($expected, $value, "Test date_day_of_week_name(2009-03-01): should be $expected, found $value.");
// Test week range with calendar weeks.
variable_set('date_first_day', 0);
variable_set('date_api_use_iso8601', FALSE);
$expected = '2008-01-27 to 2008-02-03';
$result = date_week_range(5, 2008);
$value = $result[0]->format(DATE_FORMAT_DATE) . ' to ' . $result[1]->format(DATE_FORMAT_DATE);
$this->assertEqual($expected, $value, "Test calendar date_week_range(5, 2008): should be $expected, found $value.");
$expected = '2009-01-25 to 2009-02-01';
$result = date_week_range(5, 2009);
$value = $result[0]->format(DATE_FORMAT_DATE) . ' to ' . $result[1]->format(DATE_FORMAT_DATE);
$this->assertEqual($expected, $value, "Test calendar date_week_range(5, 2009): should be $expected, found $value.");
// And now with ISO weeks.
variable_set('date_first_day', 1);
variable_set('date_api_use_iso8601', TRUE);
$expected = '2008-01-28 to 2008-02-04';
$result = date_week_range(5, 2008);
$value = $result[0]->format(DATE_FORMAT_DATE) . ' to ' . $result[1]->format(DATE_FORMAT_DATE);
$this->assertEqual($expected, $value, "Test ISO date_week_range(5, 2008): should be $expected, found $value.");
$expected = '2009-01-26 to 2009-02-02';
$result = date_week_range(5, 2009);
$value = $result[0]->format(DATE_FORMAT_DATE) . ' to ' . $result[1]->format(DATE_FORMAT_DATE);
$this->assertEqual($expected, $value, "Test ISO date_week_range(5, 2009): should be $expected, found $value.");
variable_set('date_api_use_iso8601', FALSE);
// Find calendar week for a date.
variable_set('date_first_day', 0);
$expected = '09';
$value = date_week('2008-03-01');
$this->assertEqual($expected, $value, "Test date_week(2008-03-01): should be $expected, found $value.");
$expected = '10';
$value = date_week('2009-03-01');
$this->assertEqual($expected, $value, "Test date_week(2009-03-01): should be $expected, found $value.");
// Create date object from datetime string.
$input = '2009-03-07 10:30';
$timezone = 'America/Chicago';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '2009-03-07T10:30:00-06:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone): should be $expected, found $value.");
// Same during daylight savings time.
$input = '2009-06-07 10:30';
$timezone = 'America/Chicago';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '2009-06-07T10:30:00-05:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone): should be $expected, found $value.");
// Create date object from date string.
$input = '2009-03-07';
$timezone = 'America/Chicago';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '2009-03-07T00:00:00-06:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone): should be $expected, found $value.");
// Same during daylight savings time.
$input = '2009-06-07';
$timezone = 'America/Chicago';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '2009-06-07T00:00:00-05:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone): should be $expected, found $value.");
// Create date object from date array, date only.
$input = array('year' => 2010, 'month' => 2, 'day' => 28);
$timezone = 'America/Chicago';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '2010-02-28T00:00:00-06:00';
$this->assertEqual($expected, $value, "Test new dateObject(array('year' => 2010, 'month' => 2, 'day' => 28), $timezone): should be $expected, found $value.");
// Create date object from date array with hour.
$input = array('year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10);
$timezone = 'America/Chicago';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '2010-02-28T10:00:00-06:00';
$this->assertEqual($expected, $value, "Test new dateObject(array('year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10), $timezone): should be $expected, found $value.");
// 0 = January 1, 1970 00:00:00 (UTC);
// 1000000000 = September 9, 2001 01:46:40 (UTC);
// Create date object from unix timestamp and convert it to a local date.
$input = 0;
$timezone = 'UTC';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '1970-01-01T00:00:00+00:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone): should be $expected, found $value.");
$expected = 'UTC';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone is $value: should be $expected.");
$expected = 0;
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset is $value: should be $expected.");
$timezone = 'America/Los_Angeles';
$date->setTimezone(new DateTimeZone($timezone));
$value = $date->format('c');
$expected = '1969-12-31T16:00:00-08:00';
$this->assertEqual($expected, $value, "Test \$date->setTimezone(new DateTimeZone($timezone)): should be $expected, found $value.");
$expected = 'America/Los_Angeles';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone should be $expected, found $value.");
$expected = '-28800';
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset should be $expected, found $value.");
// Convert the local version of a timestamp to UTC.
$input = 0;
$timezone = 'America/Los_Angeles';
$date = new dateObject($input, $timezone);
$offset = $date->getOffset();
$value = $date->format('c');
$expected = '1969-12-31T16:00:00-08:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone): should be $expected, found $value.");
$expected = 'America/Los_Angeles';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone should be $expected, found $value.");
$expected = '-28800';
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset should be $expected, found $value.");
$timezone = 'UTC';
$date->setTimezone(new DateTimeZone($timezone));
$value = $date->format('c');
$expected = '1970-01-01T00:00:00+00:00';
$this->assertEqual($expected, $value, "Test \$date->setTimezone(new DateTimeZone($timezone)): should be $expected, found $value.");
$expected = 'UTC';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone should be $expected, found $value.");
$expected = '0';
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset should be $expected, found $value.");
// Create date object from datetime string and convert it to a local date.
$input = '1970-01-01 00:00:00';
$timezone = 'UTC';
$date = new dateObject($input, $timezone);
$value = $date->format('c');
$expected = '1970-01-01T00:00:00+00:00';
$this->assertEqual($expected, $value, "Test new dateObject('$input', '$timezone'): should be $expected, found $value.");
$expected = 'UTC';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone is $value: should be $expected.");
$expected = 0;
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset is $value: should be $expected.");
$timezone = 'America/Los_Angeles';
$date->setTimezone(new DateTimeZone($timezone));
$value = $date->format('c');
$expected = '1969-12-31T16:00:00-08:00';
$this->assertEqual($expected, $value, "Test \$date->setTimezone(new DateTimeZone($timezone)): should be $expected, found $value.");
$expected = 'America/Los_Angeles';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone should be $expected, found $value.");
$expected = '-28800';
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset should be $expected, found $value.");
// Convert the local version of a datetime string to UTC.
$input = '1969-12-31 16:00:00';
$timezone = 'America/Los_Angeles';
$date = new dateObject($input, $timezone);
$offset = $date->getOffset();
$value = $date->format('c');
$expected = '1969-12-31T16:00:00-08:00';
$this->assertEqual($expected, $value, "Test new dateObject('$input', '$timezone'): should be $expected, found $value.");
$expected = 'America/Los_Angeles';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone should be $expected, found $value.");
$expected = '-28800';
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset should be $expected, found $value.");
$timezone = 'UTC';
$date->setTimezone(new DateTimeZone($timezone));
$value = $date->format('c');
$expected = '1970-01-01T00:00:00+00:00';
$this->assertEqual($expected, $value, "Test \$date->setTimezone(new DateTimeZone($timezone)): should be $expected, found $value.");
$expected = 'UTC';
$value = $date->getTimeZone()->getName();
$this->assertEqual($expected, $value, "The current timezone should be $expected, found $value.");
$expected = '0';
$value = $date->getOffset();
$this->assertEqual($expected, $value, "The current offset should be $expected, found $value.");
// Create year-only date.
$input = '2009';
$timezone = NULL;
$format = 'Y';
$date = new dateObject($input, $timezone, $format);
$value = $date->format('Y');
$expected = '2009';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone, $format): should be $expected, found $value.");
// Create month and year-only date.
$input = '2009-10';
$timezone = NULL;
$format = 'Y-m';
$date = new dateObject($input, $timezone, $format);
$value = $date->format('Y-m');
$expected = '2009-10';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone, $format): should be $expected, found $value.");
// Create time-only date.
$input = '0000-00-00T10:30:00';
$timezone = NULL;
$format = 'Y-m-d\TH:i:s';
$date = new dateObject($input, $timezone, $format);
$value = $date->format('H:i:s');
$expected = '10:30:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone, $format): should be $expected, found $value.");
// Create time-only date.
$input = '10:30:00';
$timezone = NULL;
$format = 'H:i:s';
$date = new dateObject($input, $timezone, $format);
$value = $date->format('H:i:s');
$expected = '10:30:00';
$this->assertEqual($expected, $value, "Test new dateObject($input, $timezone, $format): should be $expected, found $value.");
// Test date ranges.
$valid = array(
'-20:+20',
'-1:+0',
'-10:-5',
'2000:2020',
'-10:2010',
'1980:-10',
'1920:+20',
);
$invalid = array(
'abc',
'abc:+20',
'1920:+20a',
'+-20:+-30',
'12:12',
'0:+20',
'-20:0',
);
foreach ($valid as $range) {
$this->assertTrue(date_range_valid($range), "$range recognized as a valid date range.");
}
foreach ($invalid as $range) {
$this->assertFalse(date_range_valid($range), "$range recognized as an invalid date range.");
}
// Test for invalid month names when we are using a short version of the month
$input = '23 abc 2012';
$timezone = NULL;
$format = 'd M Y';
$date = new dateObject($input, $timezone, $format);
$this->assertNotEqual(count($date->errors), 0, '23 abc 2012 should be an invalid date');
}
/**
* @todo.
*/
public function tearDown() {
variable_del('date_first_day');
variable_del('date_api_use_iso8601');
parent::tearDown();
}
}

View File

@@ -0,0 +1,264 @@
<?php
/**
* @file
* Basic functions for Date tests.
*/
abstract class DateFieldBasic extends DrupalWebTestCase {
protected $privileged_user;
/**
* @todo.
*/
protected function setUp() {
// Load the date_api module.
parent::setUp('field', 'field_ui', 'date_api', 'date', 'date_popup', 'date_tools');
// Create and log in our privileged user.
$this->privileged_user = $this->drupalCreateUser(
array('administer content types', 'administer nodes', 'bypass node access', 'administer date tools')
);
$this->drupalLogin($this->privileged_user);
variable_set('date_popup_timepicker', 'none');
module_load_include('inc', 'node', 'content_types');
module_load_include('inc', 'node', 'node.pages');
module_load_include('inc', 'field', 'field.crud');
module_load_include('inc', 'date', 'date_admin');
$edit = array();
$edit['name'] = 'Story';
$edit['type'] = 'story';
$this->drupalPost('admin/structure/types/add', $edit, t('Save content type'));
$this->assertText('The content type Story has been added.', 'Content type added.');
}
/**
* Creates a date field from an array of settings values.
*
* All values have defaults, only need to specify values that need to be
* different.
*/
protected function createDateField($values = array()) {
extract($values);
$field_name = !empty($field_name) ? $field_name : 'field_test';
$entity_type = !empty($entity_type) ? $entity_type : 'node';
$bundle = !empty($bundle) ? $bundle : 'story';
$label = !empty($label) ? $label : 'Test';
$field_type = !empty($field_type) ? $field_type : 'datetime';
$repeat = !empty($repeat) ? $repeat : 0;
$todate = !empty($todate) ? $todate : 'optional';
$widget_type = !empty($widget_type) ? $widget_type : 'date_select';
$tz_handling = !empty($tz_handing) ? $tz_handling : 'site';
$granularity = !empty($granularity) ? $granularity : array('year', 'month', 'day', 'hour', 'minute');
$year_range = !empty($year_range) ? $year_range : '2010:+1';
$input_format = !empty($input_format) ? $input_format : date_default_format($widget_type);
$input_format_custom = !empty($input_format_custom) ? $input_format_custom : '';
$text_parts = !empty($text_parts) ? $text_parts : array();
$increment = !empty($increment) ? $increment : 15;
$default_value = !empty($default_value) ? $default_value : 'now';
$default_value2 = !empty($default_value2) ? $default_value2 : 'blank';
$default_format = !empty($default_format) ? $default_format : 'long';
$cache_enabled = !empty($cache_enabled);
$cache_count = !empty($cache_count) ? $cache_count : 4;
$field = array(
'field_name' => $field_name,
'type' => $field_type,
'cardinality' => !empty($repeat) ? FIELD_CARDINALITY_UNLIMITED : 1,
'settings' => array(
'granularity' => $granularity,
'tz_handling' => $tz_handling,
'timezone_db' => date_get_timezone_db($tz_handling),
'repeat' => $repeat,
'todate' => $todate,
'cache_enabled' => $cache_enabled,
'cache_count' => $cache_count,
),
);
$instance = array(
'entity_type' => $entity_type,
'field_name' => $field_name,
'label' => $label,
'bundle' => $bundle,
// Move the date right below the title.
'weight' => -4,
'widget' => array(
'type' => $widget_type,
// Increment for minutes and seconds, can be 1, 5, 10, 15, or 30.
'settings' => array(
'increment' => $increment,
// The number of years to go back and forward in drop-down year
// selectors.
'year_range' => $year_range,
'input_format' => $input_format,
'input_format_custom' => $input_format_custom,
'text_parts' => $text_parts,
'label_position' => 'above',
'repeat_collapsed' => 0,
),
'weight' => -4,
),
'settings' => array(
'default_value' => $default_value,
'default_value2' => $default_value2,
),
);
$instance['display'] = array(
'default' => array(
'label' => 'above',
'type' => 'date_default',
'settings' => array(
'format_type' => $default_format,
'show_repeat_rule' => 'show',
'multiple_number' => '',
'multiple_from' => '',
'multiple_to' => '',
'fromto' => 'both',
),
'module' => 'date',
'weight' => 0 ,
),
'teaser' => array(
'label' => 'above',
'type' => 'date_default',
'weight' => 0,
'settings' => array(
'format_type' => $default_format,
'show_repeat_rule' => 'show',
'multiple_number' => '',
'multiple_from' => '',
'multiple_to' => '',
'fromto' => 'both',
),
'module' => 'date',
),
);
$field = field_create_field($field);
$instance = field_create_instance($instance);
field_info_cache_clear(TRUE);
field_cache_clear(TRUE);
// Look at how the field got configured.
$this->drupalGet("admin/structure/types/manage/$bundle/fields/$field_name");
$this->drupalGet("admin/structure/types/manage/$bundle/display");
}
/**
* @todo.
*/
protected function deleteDateField($label, $bundle = 'story', $bundle_name = 'Story') {
$this->drupalGet("admin/structure/types/manage/$bundle/fields");
$this->clickLink('delete');
$this->drupalPost(NULL, NULL, t('Delete'));
$this->assertText("The field $label has been deleted from the $bundle_name content type.", 'Removed date field.');
}
}
class DateFieldTestCase extends DateFieldBasic {
/**
* @todo.
*/
public static function getInfo() {
return array(
'name' => 'Date Field',
'description' => 'Test date field settings and Start/End date interaction.',
'group' => 'Date',
);
}
/**
* @todo.
*/
public function testField() {
// Create a date fields with simple values.
foreach (array('date', 'datestamp', 'datetime') as $field_type) {
foreach (array('date_select', 'date_popup', 'date_text') as $widget_type) {
$field_name = "field_test_$widget_type";
$label = 'Test';
$options = array(
'label' => $label,
'widget_type' => $widget_type,
'field_name' => $field_name,
'field_type' => $field_type,
'input_format' => 'm/d/Y - H:i',
);
$this->createDateField($options);
$this->dateForm($field_name, $field_type, $widget_type);
$this->deleteDateField($label);
}
}
}
/**
* @todo.
*/
public function dateForm($field_name, $field_type, $widget_type, $todate = TRUE) {
// Tests that date field functions properly.
$edit = array();
$edit['title'] = $this->randomName(8);
if ($widget_type == 'date_select') {
$edit[$field_name . '[und][0][value][year]'] = '2010';
$edit[$field_name . '[und][0][value][month]'] = '10';
$edit[$field_name . '[und][0][value][day]'] = '7';
$edit[$field_name . '[und][0][value][hour]'] = '10';
$edit[$field_name . '[und][0][value][minute]'] = '30';
if ($todate) {
$edit[$field_name . '[und][0][show_todate]'] = '1';
$edit[$field_name . '[und][0][value2][year]'] = '2010';
$edit[$field_name . '[und][0][value2][month]'] = '10';
$edit[$field_name . '[und][0][value2][day]'] = '7';
$edit[$field_name . '[und][0][value2][hour]'] = '11';
$edit[$field_name . '[und][0][value2][minute]'] = '30';
}
}
elseif ($widget_type == 'date_text') {
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10:30';
if ($todate) {
$edit[$field_name . '[und][0][show_todate]'] = '1';
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11:30';
}
}
elseif ($widget_type == 'date_popup') {
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010';
$edit[$field_name . '[und][0][value][time]'] = '10:30';
if ($todate) {
$edit[$field_name . '[und][0][show_todate]'] = '1';
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010';
$edit[$field_name . '[und][0][value2][time]'] = '11:30';
}
}
// Test that the date is displayed correctly using both the 'short' and
// 'long' date types.
//
// For the short type, save an explicit format and assert that is the one
// which is displayed.
variable_set('date_format_short', 'l, m/d/Y - H:i:s');
$instance = field_info_instance('node', $field_name, 'story');
$instance['display']['default']['settings']['format_type'] = 'short';
field_update_instance($instance);
$this->drupalPost('node/add/story', $edit, t('Save'));
$this->assertText($edit['title'], "Node has been created");
$should_be = $todate ? 'Thursday, 10/07/2010 - 10:30 to 11:30' : 'Thursday, 10/07/2010 - 10:30';
$this->assertText($should_be, "Found the correct date for a $field_type field using the $widget_type widget displayed using the short date format.");
// For the long format, do not save anything, and assert that the displayed
// date uses the expected default value of this format provided by Drupal
// core ('l, F j, Y - H:i').
$instance = field_info_instance('node', $field_name, 'story');
$instance['display']['default']['settings']['format_type'] = 'long';
field_update_instance($instance);
$this->drupalPost('node/add/story', $edit, t('Save'));
$this->assertText($edit['title'], "Node has been created");
$should_be = $todate ? 'Thursday, October 7, 2010 - 10:30 to 11:30' : 'Thursday, October 7, 2010 - 10:30';
$this->assertText($should_be, "Found the correct date for a $field_type field using the $widget_type widget displayed using the long date format.");
}
}

View File

@@ -0,0 +1,97 @@
<?php
/**
* @file
* Timezone tests.
*/
class DateTimezoneTestCase extends DateFieldBasic {
/**
* @todo.
*/
public static function getInfo() {
return array(
'name' => 'Timezone & Granularity',
'description' => 'Test combinations of date field timezone handling and granularity.',
'group' => 'Date',
);
}
/**
* @todo.
*/
public function testTimezone() {
// Create a date fields with combinations of various timezone handling and
// granularity.
foreach (array('date', 'datestamp', 'datetime') as $field_type) {
foreach (array('site', 'none', 'date', 'user', 'utc') as $tz_handling) {
foreach (array('year', 'month', 'day', 'hour', 'minute', 'second') as $max_granularity) {
// Skip invalid combinations.
if (in_array($max_granularity, array('year', 'month', 'day')) && $tz_handling != 'none') {
continue;
}
$field_name = "field_test";
$label = 'Test';
$granularity = date_granularity_array_from_precision($max_granularity);
$options = array(
'label' => $label,
'widget_type' => 'date_text',
'field_name' => $field_name,
'field_type' => $field_type,
'input_format' => 'custom',
'input_format_custom' => 'm/d/Y - H:i:s',
'tz_handling' => $tz_handling,
'granularity' => $granularity,
);
$this->createDateField($options);
$this->dateForm($field_name, $field_type, $max_granularity, $tz_handling);
$this->deleteDateField($label);
}
}
}
}
/**
* @todo.
*/
public function dateForm($field_name, $field_type, $max_granularity, $tz_handling) {
variable_set('date_format_long', 'D, m/d/Y - H:i:s');
$edit = array();
$edit['title'] = $this->randomName(8);
$edit[$field_name . '[und][0][show_todate]'] = '1';
switch ($max_granularity) {
case 'year':
$edit[$field_name . '[und][0][value][date]'] = '2010';
$edit[$field_name . '[und][0][value2][date]'] = '2011';
$should_be = '2010 to 2011';
break;
case 'month':
$edit[$field_name . '[und][0][value][date]'] = '07/2010';
$edit[$field_name . '[und][0][value2][date]'] = '08/2010';
$should_be = '07/2010 to 08/2010';
break;
case 'day':
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010';
$edit[$field_name . '[und][0][value2][date]'] = '10/08/2010';
$should_be = 'Thu, 10/07/2010 to Fri, 10/08/2010';
break;
case 'hour':
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10';
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11';
$should_be = 'Thu, 10/07/2010 - 10 to Thu, 10/07/2010 - 11';
break;
case 'minute':
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10:30';
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11:30';
$should_be = 'Thu, 10/07/2010 - 10:30 to 11:30';
break;
case 'second':
$edit[$field_name . '[und][0][value][date]'] = '10/07/2010 - 10:30:30';
$edit[$field_name . '[und][0][value2][date]'] = '10/07/2010 - 11:30:30';
$should_be = 'Thu, 10/07/2010 - 10:30:30 to 11:30:30';
break;
}
$this->drupalPost('node/add/story', $edit, t('Save'));
$this->assertText($edit['title'], "Node has been created");
$this->assertText($should_be, "Found the correct date for a $field_type field using $max_granularity granularity with $tz_handling timezone handling.");
}
}

View File

@@ -0,0 +1,151 @@
<?php
/**
* @file
* Date validation tests.
*/
class DateValidationTestCase extends DateFieldBasic {
/**
* @todo.
*/
public static function getInfo() {
return array(
'name' => 'Date Validation',
'description' => 'Test date validation.',
'group' => 'Date',
);
}
/**
* @todo.
*/
public function testValidation() {
// Attempts to create text date field stored as a date with default settings
// (from input which is not valid).
foreach (array('date', 'datestamp', 'datetime') as $field_type) {
foreach (array('date_select', 'date_popup', 'date_text') as $widget_type) {
$field_name = 'field_test';
$label = 'Test';
$options = array(
'label' => $label,
'field_name' => $field_name,
'field_type' => $field_type,
'widget_type' => $widget_type,
'input_format' => 'm/d/Y - H:i',
);
$this->createDateField($options);
// Malformed date test won't work on date_select, which won't allow
// invalid input.
if ($widget_type != 'date_select') {
$this->malFormedDate($field_name, $field_type, $widget_type);
}
$this->wrongGranularity($field_name, $field_type, $widget_type);
$this->deleteDateField($label);
}
}
}
/**
* @todo.
*/
function malFormedDate($field_name, $field_type, $widget_type) {
// Tests that date field filters improper dates.
$edit = array();
$edit['title'] = $this->randomName(8);
$edit['body[und][0][value]'] = $this->randomName(16);
if ($widget_type == 'date_select') {
$edit[$field_name . '[und][0][value][year]'] = '2011';
$edit[$field_name . '[und][0][value][month]'] = '15';
$edit[$field_name . '[und][0][value][day]'] = '49';
$edit[$field_name . '[und][0][value][hour]'] = '10';
$edit[$field_name . '[und][0][value][minute]'] = '30';
}
elseif ($widget_type == 'date_text') {
$edit[$field_name . '[und][0][value][date]'] = '15/49/2011 - 10:30';
}
elseif ($widget_type == 'date_popup') {
$edit[$field_name . '[und][0][value][date]'] = '15/49/2011';
$edit[$field_name . '[und][0][value][time]'] = '10:30';
}
$this->drupalPost('node/add/story', $edit, t('Save'));
$should_not_be = $edit['title'] . "has been created";
$this->assertNoText($should_not_be, "Correctly blocked creation of node with invalid month and day for a $field_type field using the $widget_type widget.");
$this->assertText('The month is invalid.', "Correctly blocked invalid month for a $field_type field using the $widget_type widget.");
$this->assertText('The day is invalid.', "Correctly blocked invalid day for a $field_type field using the $widget_type widget.");
// Test two-digit entry for year where 4-digit is expected.
if ($widget_type == 'date_select') {
$edit[$field_name . '[und][0][value][year]'] = '11';
$edit[$field_name . '[und][0][value][month]'] = '12';
$edit[$field_name . '[und][0][value][day]'] = '10';
$edit[$field_name . '[und][0][value][hour]'] = '10';
$edit[$field_name . '[und][0][value][minute]'] = '30';
}
elseif ($widget_type == 'date_text') {
$edit[$field_name . '[und][0][value][date]'] = '12/10/11 - 10:30';
}
elseif ($widget_type == 'date_popup') {
$edit[$field_name . '[und][0][value][date]'] = '12/10/11';
$edit[$field_name . '[und][0][value][time]'] = '10:30';
}
$this->drupalPost('node/add/story', $edit, t('Save'));
$should_not_be = $edit['title'] . " has been created";
$this->assertNoText($should_not_be, "Correctly blocked creation of node with invalid year for a $field_type field using the $widget_type widget.");
$should_be = 'The year is invalid. Please check that entry includes four digits.';
$this->assertText($should_be, "Correctly blocked two digit year for a $field_type field using the $widget_type widget.");
// Test invalid hour/minute entry for time.
if ($widget_type == 'date_select') {
$edit[$field_name . '[und][0][value][year]'] = '2011';
$edit[$field_name . '[und][0][value][month]'] = '12';
$edit[$field_name . '[und][0][value][day]'] = '10';
$edit[$field_name . '[und][0][value][hour]'] = '29';
$edit[$field_name . '[und][0][value][minute]'] = '95';
}
elseif ($widget_type == 'date_text') {
$edit[$field_name . '[und][0][value][date]'] = '12/10/2011 - 29:95';
}
elseif ($widget_type == 'date_popup') {
$edit[$field_name . '[und][0][value][date]'] = '12/10/2011';
$edit[$field_name . '[und][0][value][time]'] = '29:95';
}
$this->drupalPost('node/add/story', $edit, t('Save'));
$should_not_be = $edit['title'] . " has been created";
$this->assertNoText($should_not_be, "Correctly blocked creation of node with invalid time for a $field_type field using the $widget_type widget.");
$should_be = 'The hour is invalid.';
$this->assertText($should_be, "Correctly blocked invalid hour for a $field_type field using the $widget_type widget.");
$should_be = 'The minute is invalid.';
$this->assertText($should_be, "Correctly blocked invalid minute for a $field_type field using the $widget_type widget.");
}
/**
* @todo.
*/
public function wrongGranularity($field_name, $field_type, $widget_type) {
// Create a node with incorrect granularity -- missing time.
$edit = array();
$edit['title'] = $this->randomName(8);
$edit['body[und][0][value]'] = $this->randomName(16);
if ($widget_type == 'date_select') {
$edit[$field_name . '[und][0][value][year]'] = '2011';
$edit[$field_name . '[und][0][value][month]'] = '12';
$edit[$field_name . '[und][0][value][day]'] = '10';
$edit[$field_name . '[und][0][value][hour]'] = '';
$edit[$field_name . '[und][0][value][minute]'] = '';
}
elseif ($widget_type == 'date_text') {
$edit[$field_name . '[und][0][value][date]'] = '12/10/2011';
}
elseif ($widget_type == 'date_popup') {
$edit[$field_name . '[und][0][value][date]'] = '12/10/2011';
$edit[$field_name . '[und][0][value][time]'] = '';
}
$this->drupalPost('node/add/story', $edit, t('Save'));
$should_not_be = $edit['title'] . " has been created";
$this->assertNoText($should_not_be, "Correctly blocked creation of node with missing time for a $field_type field using the $widget_type widget.");
$this->assertText('invalid', "Marked form with missing time as invalid for a $field_type field using the $widget_type widget.");
}
}

View File

@@ -0,0 +1,125 @@
BEGIN:VCALENDAR
PRODID:-//Test
VERSION:2.0
X-WR-CALDESC:Test various iCal RRULEs.
BEGIN:VEVENT
UID:iCalRRuleTest1
SUMMARY:Daily for 10 occurrences
DTSTART;TZID=US-Eastern:20090702T090000
RRULE:FREQ=DAILY;COUNT=10
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest2
SUMMARY:Daily until December 24, 2009
DTSTART;TZID=US-Eastern:20091202T090000
RRULE:FREQ=DAILY;UNTIL=20091224T000000Z
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest3
SUMMARY:Every other day
DTSTART;TZID=US-Eastern:20090202T090000
RRULE:FREQ=DAILY;INTERVAL=2
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest4
SUMMARY:Every 10 days, 5 occurrences
DTSTART;TZID=US-Eastern:20090302T090000
RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest5
SUMMARY:Everyday in January, for 2 years
DTSTART;TZID=US-Eastern:20090101T090000
RRULE:FREQ=YEARLY;UNTIL=20110131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest6
SUMMARY:Weekly for 10 occurrences
DTSTART;TZID=US-Eastern:20090102T090000
RRULE:FREQ=WEEKLY;COUNT=10
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest7
SUMMARY:Weekly on Tuesday and Thursday for 5 weeks
DTSTART;TZID=US-Eastern:20090902T090000
RRULE:FREQ=WEEKLY;UNTIL=20091007T000000Z;WKST=SU;BYDAY=TU,TH
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest8
SUMMARY:Every other week on Monday, Wednesday and Friday until December 24, 2009:
DTSTART;TZID=US-Eastern:20090502T090000
RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20091224T000000Z;WKST=SU;BYDAY=MO,WE,FR
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest9
SUMMARY:Every other week on Tuesday and Thursday, for 8 occurrences
DTSTART;TZID=US-Eastern:20090702T090000
RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest10
SUMMARY:Monthly on the 1st Friday for ten occurrences
DTSTART;TZID=US-Eastern:20090905T090000
RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest11
SUMMARY:Monthly on the 1st Friday until December 24, 2009
DTSTART;TZID=US-Eastern:20090905T090000
RRULE:FREQ=MONTHLY;UNTIL=20091224T000000Z;BYDAY=1FR
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest12
SUMMARY:Every other month on the 1st and last Sunday of the month for 10 occurrences
DTSTART;TZID=US-Eastern:20090907T090000
RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest13
SUMMARY:Monthly on the second to last Monday of the month for 6 months
DTSTART;TZID=US-Eastern:20090119T090000
RRULE:FREQ=MONTHLY;COUNT=6;BYDAY=-2MO
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest14
SUMMARY:Monthly on the third to the last day of the month
DTSTART;TZID=US-Eastern:20090928T090000
RRULE:FREQ=MONTHLY;BYMONTHDAY=-3
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest15
SUMMARY:Monthly on the 2nd and 15th of the month for 10 occurrences
DTSTART;TZID=US-Eastern:20090202T090000
RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest16
SUMMARY:Monthly on the first and last day of the month for 10 occurrences
DTSTART;TZID=US-Eastern:20090130T090000
RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest17
SUMMARY:Every 3 months on the 10th thru 15th of the month for 10 occurrences
DTSTART;TZID=US-Eastern:20090410T090000
RRULE:FREQ=MONTHLY;INTERVAL=3;COUNT=10;BYMONTHDAY=10,11,12,13,14,15
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest18
SUMMARY:Every Tuesday, every other month
DTSTART;TZID=US-Eastern:20090602T090000
RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=TU
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest19
SUMMARY:Yearly in June and July for 10 occurrences
DTSTART;TZID=US-Eastern:20090610T090000
RRULE:FREQ=YEARLY;COUNT=10;BYMONTH=6,7
END:VEVENT
BEGIN:VEVENT
UID:iCalRRuleTest20
SUMMARY:Every Thursday in March
DTSTART;TZID=US-Eastern:20090305T090000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=TH
END:VEVENT
END:VCALENDAR