Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

changed assert_cannot_parse to test only the current parse level, not…

… both, because some parsers can parse in lax, but not in strict; changed rdoc to use =begin ... =end format for in-file readability and editability
  • Loading branch information...
commit 852e9de3a34f79dfedda8fc65e85ddba522053a8 1 parent 655271c
@jamesarosen authored
View
2  doc/RFC_2445.rdoc
@@ -1562,7 +1562,7 @@ defined for this value type.
Example: The following is an example of a hypothetical property that
has a BOOLEAN value type:
-GIBBERISH:TRUE
+ GIBBERISH:TRUE
===== 4.3.3 Calendar User Address
View
2  lib/rcal/util/whole_line_regex.rb
@@ -2,7 +2,7 @@ class Regexp
# Returns a new Regexp that is the same as this with both a start and an end anchor.
def to_whole_line
- Regexp.new("^(?:#{self})$")
+ Regexp.new("\\A(?:#{self})\\Z")
end
end
View
42 lib/rcal/value/binary.rb
@@ -1,17 +1,45 @@
require 'rcal/value/parser'
+=begin
+4.3.1 Binary
+
+Value Name: BINARY
+
+Purpose: This value type is used to identify properties that contain
+a character encoding of inline binary data. For example, an inline
+attachment of an object code might be included in an iCalendar
+object.
+
+Formal Definition: The value type is defined by the following
+notation:
+
+ binary = *(4b-char) [b-end]
+ ; A "BASE64" encoded character string, as defined by [RFC 2045].
+
+ b-end = (2b-char "==") / (3b-char "=")
+
+ b-char = ALPHA / DIGIT / "+" / "/"
+
+Description: Property values with this value type MUST also include
+the inline encoding parameter sequence of ";ENCODING=BASE64". That
+is, all inline binary data MUST first be character encoded using the
+"BASE64" encoding method defined in [RFC 2045]. No additional content
+value encoding (i.e., BACKSLASH character encoding) is defined for
+this value type.
+
+Example: The following is an abridged example of a "BASE64" encoded
+binary value data.
+
+ ATTACH;VALUE=BINARY;ENCODING=BASE64:MIICajCCAdOgAwIBAgICBEUwDQY
+ JKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlI
+ ENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZv
+ <...remainder of "BASE64" encoded binary data...>
+=end
class Rcal::Value::BinaryParser < Rcal::Value::Parser
binary_char = /[a-zA-Z0-9\+\/]/
binary_end = Regexp.new("(?:#{binary_char.source}{2}==)|(?:#{binary_char.source}{3}=)")
- # From {RFC 2445 4.3.1}[link:/files/doc/RFC_2445_rdoc.html]:
- # binary = *(4b-char) [b-end]
- # ; A "BASE64" encoded character string, as defined by [RFC 2045].
- #
- # b-end = (2b-char "==") / (3b-char "=")
- #
- # b-char = ALPHA / DIGIT / "+" / "/"
BINARY = Regexp.new("(?:#{binary_char.source}{4})*(?:#{binary_end.source})?")
# Returns +true+ iff +ical+ is Base64-encoded binary data.
View
24 lib/rcal/value/boolean.rb
@@ -1,9 +1,29 @@
require 'rcal/value/parser'
+=begin
+4.3.2 Boolean
+
+Value Name: BOOLEAN
+
+Purpose: This value type is used to identify properties that contain
+either a "TRUE" or "FALSE" Boolean value.
+
+Formal Definition: The value type is defined by the following
+notation:
+
+ boolean = "TRUE" / "FALSE"
+
+Description: These values are case insensitive text. No additional
+content value encoding (i.e., BACKSLASH character encoding) is
+defined for this value type.
+
+Example: The following is an example of a hypothetical property that
+has a BOOLEAN value type:
+
+ GIBBERISH:TRUE
+=end
class Rcal::Value::BooleanParser < Rcal::Value::Parser
- # From {RFC 2445 4.3.2}[link:/files/doc/RFC_2445_rdoc.html]:
- # boolean = "TRUE" / "FALSE"
BOOLEAN = /TRUE|FALSE/
# Returns +true+ iff +ical+ is "TRUE" or "FALSE".
View
24 lib/rcal/value/cal_address.rb
@@ -1,5 +1,29 @@
require 'rcal/value/uri'
+=begin
+4.3.3 Calendar User Address
+
+Value Name: CAL-ADDRESS
+
+Purpose: This value type is used to identify properties that contain
+a calendar user address.
+
+Formal Definition: The value type is as defined by the following
+notation:
+
+ cal-address = uri
+
+Description: The value is a URI as defined by [RFC 1738] or any other
+IANA registered form for a URI. When used to address an Internet
+email transport address for a calendar user, the value MUST be a
+MAILTO URI, as defined by [RFC 1738]. No additional content value
+encoding (i.e., BACKSLASH character encoding) is defined for this
+value type.
+
+Example:
+
+ ATTENDEE:MAILTO:jane_doe@host.com
+=end
class Rcal::Value::CalAddressParser < Rcal::Value::UriParser
# Returns 'CAL-ADDRESS'.
View
43 lib/rcal/value/date.rb
@@ -1,20 +1,45 @@
require 'rcal/value/parser'
+=begin
+4.3.4 Date
+
+Value Name: DATE
+
+Purpose: This value type is used to identify values that contain a
+calendar date.
+
+Formal Definition: The value type is defined by the following
+notation:
+
+ date = date-value
+
+ date-value = date-fullyear date-month date-mday
+ date-fullyear = 4DIGIT
+ date-month = 2DIGIT ;01-12
+ date-mday = 2DIGIT ;01-28, 01-29, 01-30, 01-31
+ ;based on month/year
+
+Description: If the property permits, multiple "date" values are
+specified as a COMMA character (US-ASCII decimal 44) separated list
+of values. The format for the value type is expressed as the [ISO 8601]
+complete representation, basic format for a calendar date. The
+textual format specifies a four-digit year, two-digit month, and
+two-digit day of the month. There are no separator characters between
+the year, month and day component text.
+
+No additional content value encoding (i.e., BACKSLASH character
+encoding) is defined for this value type.
+
+Example: The following represents July 14, 1997:
+
+ 19970714
+=end
class Rcal::Value::DateParser < Rcal::Value::Parser
day = /(?:0[1-9])|(?:[1-2][0-9])|(?:3[01])/
month = /(?:0[1-9])|(?:1[0-2])/
year = /[0-9]{4}/
- # From {RFC 2445 4.3.4}[link:/files/doc/RFC_2445_rdoc.html]:
- # date = date-value
- #
- # date-value = date-fullyear date-month date-mday
- # date-fullyear = 4DIGIT
- # date-month = 2DIGIT ;01-12
- # date-mday = 2DIGIT ;01-28, 01-29, 01-30, 01-31
- # ;based on month/year
- #
# Matchdata:
# 0. Whole date string
# 1. Year
View
104 lib/rcal/value/date_time.rb
@@ -2,15 +2,111 @@
require 'rcal/value/date'
require 'rcal/value/time_of_day'
+=begin
+4.3.5 Date-Time
+
+Value Name: DATE-TIME
+
+Purpose: This value type is used to identify values that specify a
+precise calendar date and time of day.
+
+Formal Definition: The value type is defined by the following
+notation:
+
+ date-time = date "T" time ;As specified in the date and time
+ ;value definitions
+
+Description: If the property permits, multiple "date-time" values are
+specified as a COMMA character (US-ASCII decimal 44) separated list
+of values. No additional content value encoding (i.e., BACKSLASH
+character encoding) is defined for this value type.
+
+The "DATE-TIME" data type is used to identify values that contain a
+precise calendar date and time of day. The format is based on the [ISO 8601]
+complete representation, basic format for a calendar date
+and time of day. The text format is a concatenation of the "date",
+followed by the LATIN CAPITAL LETTER T character (US-ASCII decimal 84)
+time designator, followed by the "time" format.
+
+The "DATE-TIME" data type expresses time values in three forms:
+
+The form of date and time with UTC offset MUST NOT be used. For
+example, the following is not valid for a date-time value:
+
+ DTSTART:19980119T230000-0800 ;Invalid time format
+
+FORM #1: DATE WITH LOCAL TIME
+
+The date with local time form is simply a date-time value that does
+not contain the UTC designator nor does it reference a time zone. For
+example, the following represents Janurary 18, 1998, at 11 PM:
+
+ DTSTART:19980118T230000
+
+Date-time values of this type are said to be "floating" and are not
+bound to any time zone in particular. They are used to represent the
+same hour, minute, and second value regardless of which time zone is
+currently being observed. For example, an event can be defined that
+indicates that an individual will be busy from 11:00 AM to 1:00 PM
+every day, no matter which time zone the person is in. In these
+cases, a local time can be specified. The recipient of an iCalendar
+object with a property value consisting of a local time, without any
+relative time zone information, SHOULD interpret the value as being
+fixed to whatever time zone the ATTENDEE is in at any given moment.
+This means that two ATTENDEEs, in different time zones, receiving the
+same event definition as a floating time, may be participating in the
+event at different actual times. Floating time SHOULD only be used
+where that is the reasonable behavior.
+
+In most cases, a fixed time is desired. To properly communicate a
+fixed time in a property value, either UTC time or local time with
+time zone reference MUST be specified.
+
+The use of local time in a DATE-TIME value without the TZID property
+parameter is to be interpreted as floating time, regardless of the
+existence of "VTIMEZONE" calendar components in the iCalendar object.
+
+FORM #2: DATE WITH UTC TIME
+
+The date with UTC time, or absolute time, is identified by a LATIN
+CAPITAL LETTER Z suffix character (US-ASCII decimal 90), the UTC
+designator, appended to the time value. For example, the following
+represents January 19, 1998, at 0700 UTC:
+
+ DTSTART:19980119T070000Z
+
+The TZID property parameter MUST NOT be applied to DATE-TIME
+properties whose time values are specified in UTC.
+
+FORM #3: DATE WITH LOCAL TIME AND TIME ZONE REFERENCE
+
+The date and local time with reference to time zone information is
+identified by the use the TZID property parameter to reference the
+appropriate time zone definition. TZID is discussed in detail in the
+section on Time Zone. For example, the following represents 2 AM in
+New York on Janurary 19, 1998:
+
+ DTSTART;TZID=US-Eastern:19980119T020000
+
+Example: The following represents July 14, 1997, at 1:30 PM in New
+York City in each of the three time formats, using the "DTSTART"
+property.
+
+ DTSTART:19970714T133000 ;Local time
+ DTSTART:19970714T173000Z ;UTC time
+ DTSTART;TZID=US-Eastern:19970714T133000 ;Local time and time
+ ; zone reference
+
+A time value MUST ONLY specify 60 seconds when specifying the
+periodic "leap second" in the time value. For example:
+
+ COMPLETED:19970630T235960Z
+=end
class Rcal::Value::DateTimeParser < Rcal::Value::Parser
date = Rcal::Value::DateParser::DATE
time = Rcal::Value::TimeOfDay::TIME
- # From {RFC 2445 4.3.5}[link:/files/doc/RFC_2445_rdoc.html]:
- # date-time = date "T" time ;As specified in the date and time
- # ;value definitions
- #
# Matchdata:
# 0. whole string
# 1. 4-digit year
View
63 lib/rcal/value/duration.rb
@@ -1,19 +1,45 @@
require 'rcal/value/parser'
-# Value class representing a duration.
+=begin
+4.3.6 Duration
+
+Value Name: DURATION
+
+Purpose: This value type is used to identify properties that contain
+a duration of time.
+
+Formal Definition: The value type is defined by the following
+notation:
+
+ dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
+
+ dur-date = dur-day [dur-time]
+ dur-time = "T" (dur-hour / dur-minute / dur-second)
+ dur-week = 1*DIGIT "W"
+ dur-hour = 1*DIGIT "H" [dur-minute]
+ dur-minute = 1*DIGIT "M" [dur-second]
+ dur-second = 1*DIGIT "S"
+ dur-day = 1*DIGIT "D"
+
+Description: If the property permits, multiple "duration" values are
+specified by a COMMA character (US-ASCII decimal 44) separated list
+of values. The format is expressed as the [ISO 8601] basic format for
+the duration of time. The format can represent durations in terms of
+weeks, days, hours, minutes, and seconds.
+
+No additional content value encoding (i.e., BACKSLASH character
+encoding) are defined for this value type.
+
+Example: A duration of 15 days, 5 hours and 20 seconds would be:
+
+ P15DT5H0M20S
+
+A duration of 7 weeks would be:
+
+ P7W
+=end
class Rcal::Value::Duration
- # From {RFC 2445 4.3.6}[link:/files/doc/RFC_2445_rdoc.html]:
- # dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
- #
- # dur-date = dur-day [dur-time]
- # dur-time = "T" (dur-hour / dur-minute / dur-second)
- # dur-week = 1*DIGIT "W"
- # dur-hour = 1*DIGIT "H" [dur-minute]
- # dur-minute = 1*DIGIT "M" [dur-second]
- # dur-second = 1*DIGIT "S"
- # dur-day = 1*DIGIT "D"
- #
# Matchdata:
# 0. Whole duration string
# 1. Sign ('+', '-' or +nil+)
@@ -62,7 +88,11 @@ def validate!
weeks > 0 && [days, hours, minutes, seconds].any? { |u| u > 0 }
raise ArgumentError.new("Durations must have at least one of [weeks, days, hours, minutes, seconds]") if
[weeks, days, hours, minutes, seconds].all? { |u| u == 0 }
+ raise ArgumentError.new("Use sign instead of negative values for negative durations") if
+ [weeks, days, hours, minutes, seconds].any? { |u| u < 0 }
end
+
+ private :validate!
def positive?
sign != '-'
@@ -79,6 +109,13 @@ def from(time)
time + in_seconds
end
+ # Returns a Range(Time..Time) that starts at +time+ and has length of
+ # <tt>self.in_seconds</tt> seconds. The returned Range is exclusive
+ # if +exclusive+ is +true+ (it is +false+ by default).
+ def starting_at(time, exclusive = false)
+ Range.new(time, self.from(time), exclusive)
+ end
+
# Returns this duration as an Integer number of seconds.
def in_seconds
multiplier = positive? ? 1 : -1
@@ -97,8 +134,6 @@ def to_ical
result << "#{seconds}S" if seconds > 0
return result
end
-
- private :validate!
# Parser for Durations.
View
28 lib/rcal/value/float.rb
@@ -1,9 +1,33 @@
require 'rcal/value/parser'
+=begin
+4.3.7 Float
+
+Value Name: FLOAT
+
+Purpose: This value type is used to identify properties that contain
+a real number value.
+
+Formal Definition: The value type is defined by the following
+notation:
+
+ float = (["+"] / "-") 1*DIGIT ["." 1*DIGIT]
+
+Description: If the property permits, multiple "float" values are
+specified by a COMMA character (US-ASCII decimal 44) separated list
+of values.
+
+No additional content value encoding (i.e., BACKSLASH character
+encoding) is defined for this value type.
+
+Example:
+
+ 1000000.0000001
+ 1.333
+ -3.14
+=end
class Rcal::Value::FloatParser < Rcal::Value::Parser
- # From {RFC 2445 Section 4.3.7}[link:/files/doc/RFC_2445_rdoc.html]:
- # float = (["+"] / "-") 1*DIGIT ["." 1*DIGIT]
FLOAT = /[\+-]?[0-9]+(?:\.[0-9]+)?/
def is_parser_for?(ical)
View
33 lib/rcal/value/integer.rb
@@ -1,16 +1,43 @@
require 'rcal/value/parser'
+=begin
+4.3.8 Integer
+
+ Value Name:INTEGER
+
+ Purpose: This value type is used to identify properties that contain
+ a signed integer value.
+
+ Formal Definition: The value type is defined by the following
+ notation:
+
+ integer = (["+"] / "-") 1*DIGIT
+
+ Description: If the property permits, multiple "integer" values are
+ specified by a COMMA character (US-ASCII decimal 44) separated list
+ of values. The valid range for "integer" is -2147483648 to
+ 2147483647. If the sign is not specified, then the value is assumed
+ to be positive.
+
+ No additional content value encoding (i.e., BACKSLASH character
+ encoding) is defined for this value type.
+
+ Example:
+
+ 1234567890
+ -1234567890
+ +1234567890
+ 432109876
+=end
class Rcal::Value::IntegerParser < Rcal::Value::Parser
- # From {RFC 2445 Section 4.3.8}[link:/files/doc/RFC_2445_rdoc.html]:
- # integer = (["+"] / "-") 1*DIGIT
INTEGER = /[\+-]?[0-9]+/
def is_parser_for?(ical)
ical =~ INTEGER.to_whole_line
end
- # Returns a Ruby Float.
+ # Returns a Ruby Integer.
def parse(ical, context)
return wrong_parser!(ical, context, "#{ical} is not an integer") unless is_parser_for?(ical)
ical.to_i
View
9 test/lib/parser_test_case.rb
@@ -38,7 +38,7 @@ def assert_parses(*values)
values.each do |v|
with_compliance_level(STRICT) do
assert_nothing_raised("Should be able to parse #{v}") do
- param = parse(v)
+ param = parse(v).to_s
# TODO: implement .to_ical
# assert_equal v, param.to_ical
end
@@ -47,11 +47,12 @@ def assert_parses(*values)
end
def assert_cannot_parse(*values)
- values.each do |v|
- with_compliance_level(STRICT) do
+ if parser.compliance_level = STRICT
+ values.each do |v|
assert_raises(ParseError, "Parsing #{v} at level strict should raise a ParseError") { parse(v) }
end
- with_compliance_level(LAX) do
+ else
+ values.each do |v|
assert_nil parse(v), "Parsing #{v} at level lax should return nil"
end
end
View
7 test/value/binary_test.rb
@@ -82,7 +82,12 @@ def test_parses_strings_length_3_mod_4_padded_properly
end
def test_cannot_parse_strings_with_invalid_chars
- assert_cannot_parse *@invalid_chars
+ with_compliance_level(Rcal::Parser::STRICT) do
+ assert_cannot_parse *@invalid_chars
+ end
+ with_compliance_level(Rcal::Parser::LAX) do
+ assert_cannot_parse *@invalid_chars
+ end
end
View
10 test/value/boolean_test.rb
@@ -30,4 +30,14 @@ def test_parses_to_ruby_booleans
assert_equal false, parse('FALSE')
end
+ def test_cannot_parse_strings_with_invalid_chars
+ invalid_booleans = 'true', 'false', 't', 'f'
+ with_compliance_level(Rcal::Parser::STRICT) do
+ assert_cannot_parse *invalid_booleans
+ end
+ with_compliance_level(Rcal::Parser::LAX) do
+ assert_cannot_parse *invalid_booleans
+ end
+ end
+
end
View
12 test/value/date_test.rb
@@ -22,8 +22,16 @@ def test_is_not_parser_for_non_ical_dates
assert_is_wrong_parser_for '2005', '1565012', 'December 3, 2000'
end
- def test_error_parsing_invalid_date
- assert_cannot_parse '20000631', '20070431', '20050229'
+ def test_cannot_parse_invalid_date
+ invalid_dates = ['20000631', '20070431', '20050229']
+ def test_cannot_parse_strings_with_invalid_chars
+ with_compliance_level(Rcal::Parser::STRICT) do
+ assert_cannot_parse *invalid_dates
+ end
+ with_compliance_level(Rcal::Parser::LAX) do
+ assert_cannot_parse *invalid_dates
+ end
+ end
end
def test_parses_dates
View
8 test/value/date_time_test.rb
@@ -22,7 +22,13 @@ def test_is_parser_for_date_times
end
def test_cannot_parse_non_date_times
- assert_cannot_parse 'foo', '2001', '200101', '20010203', '20010203T', '20010203T04', '20010203T0405', '20010203040506'
+ non_date_times = 'foo', '2001', '200101', '20010203', '20010203T', '20010203T04', '20010203T0405', '20010203040506'
+ with_compliance_level(Rcal::Parser::STRICT) do
+ assert_cannot_parse *non_date_times
+ end
+ with_compliance_level(Rcal::Parser::LAX) do
+ assert_cannot_parse *non_date_times
+ end
end
def test_parses_date_times
View
8 test/value/time_of_day_test.rb
@@ -63,7 +63,13 @@ def test_is_parser_for_times_of_day
end
def test_cannot_parse_non_times_of_day
- assert_cannot_parse 'foo', '14', '1456', 'T195445'
+ non_times_of_day = 'foo', '14', '1456', 'T195445'
+ with_compliance_level(Rcal::Parser::STRICT) do
+ assert_cannot_parse *non_times_of_day
+ end
+ with_compliance_level(Rcal::Parser::LAX) do
+ assert_cannot_parse *non_times_of_day
+ end
end
def test_parses_times_of_day
Please sign in to comment.
Something went wrong with that request. Please try again.