micahwedemeyer-ri_cal 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. data/.rvmrc +2 -0
  2. data/Gemfile +7 -0
  3. data/Gemfile.lock +21 -0
  4. data/History.txt +402 -0
  5. data/Manifest.txt +161 -0
  6. data/README.txt +410 -0
  7. data/Rakefile +66 -0
  8. data/VERSION +1 -0
  9. data/bin/ri_cal +8 -0
  10. data/component_attributes/alarm.yml +10 -0
  11. data/component_attributes/calendar.yml +4 -0
  12. data/component_attributes/component_property_defs.yml +180 -0
  13. data/component_attributes/event.yml +45 -0
  14. data/component_attributes/freebusy.yml +16 -0
  15. data/component_attributes/journal.yml +35 -0
  16. data/component_attributes/timezone.yml +3 -0
  17. data/component_attributes/timezone_period.yml +11 -0
  18. data/component_attributes/todo.yml +46 -0
  19. data/copyrights.txt +1 -0
  20. data/docs/draft-ietf-calsify-2446bis-08.txt +7280 -0
  21. data/docs/draft-ietf-calsify-rfc2445bis-09.txt +10416 -0
  22. data/docs/incrementers.txt +7 -0
  23. data/docs/rfc2445.pdf +0 -0
  24. data/lib/ri_cal/component/alarm.rb +19 -0
  25. data/lib/ri_cal/component/calendar.rb +257 -0
  26. data/lib/ri_cal/component/event.rb +58 -0
  27. data/lib/ri_cal/component/freebusy.rb +16 -0
  28. data/lib/ri_cal/component/journal.rb +27 -0
  29. data/lib/ri_cal/component/non_standard.rb +33 -0
  30. data/lib/ri_cal/component/t_z_info_timezone.rb +153 -0
  31. data/lib/ri_cal/component/timezone/daylight_period.rb +25 -0
  32. data/lib/ri_cal/component/timezone/standard_period.rb +23 -0
  33. data/lib/ri_cal/component/timezone/timezone_period.rb +76 -0
  34. data/lib/ri_cal/component/timezone.rb +197 -0
  35. data/lib/ri_cal/component/todo.rb +42 -0
  36. data/lib/ri_cal/component.rb +256 -0
  37. data/lib/ri_cal/core_extensions/array/conversions.rb +15 -0
  38. data/lib/ri_cal/core_extensions/array.rb +7 -0
  39. data/lib/ri_cal/core_extensions/date/conversions.rb +56 -0
  40. data/lib/ri_cal/core_extensions/date.rb +13 -0
  41. data/lib/ri_cal/core_extensions/date_time/conversions.rb +50 -0
  42. data/lib/ri_cal/core_extensions/date_time.rb +15 -0
  43. data/lib/ri_cal/core_extensions/object/conversions.rb +20 -0
  44. data/lib/ri_cal/core_extensions/object.rb +8 -0
  45. data/lib/ri_cal/core_extensions/string/conversions.rb +57 -0
  46. data/lib/ri_cal/core_extensions/string.rb +8 -0
  47. data/lib/ri_cal/core_extensions/time/calculations.rb +153 -0
  48. data/lib/ri_cal/core_extensions/time/conversions.rb +42 -0
  49. data/lib/ri_cal/core_extensions/time/tzid_access.rb +50 -0
  50. data/lib/ri_cal/core_extensions/time/week_day_predicates.rb +55 -0
  51. data/lib/ri_cal/core_extensions/time.rb +14 -0
  52. data/lib/ri_cal/core_extensions.rb +11 -0
  53. data/lib/ri_cal/fast_date_time.rb +234 -0
  54. data/lib/ri_cal/floating_timezone.rb +32 -0
  55. data/lib/ri_cal/invalid_property_value.rb +8 -0
  56. data/lib/ri_cal/invalid_timezone_identifier.rb +20 -0
  57. data/lib/ri_cal/occurrence_enumerator.rb +265 -0
  58. data/lib/ri_cal/occurrence_period.rb +17 -0
  59. data/lib/ri_cal/parser.rb +145 -0
  60. data/lib/ri_cal/properties/alarm.rb +390 -0
  61. data/lib/ri_cal/properties/calendar.rb +164 -0
  62. data/lib/ri_cal/properties/event.rb +1523 -0
  63. data/lib/ri_cal/properties/freebusy.rb +593 -0
  64. data/lib/ri_cal/properties/journal.rb +1237 -0
  65. data/lib/ri_cal/properties/timezone.rb +150 -0
  66. data/lib/ri_cal/properties/timezone_period.rb +416 -0
  67. data/lib/ri_cal/properties/todo.rb +1559 -0
  68. data/lib/ri_cal/properties.rb +12 -0
  69. data/lib/ri_cal/property_value/array.rb +27 -0
  70. data/lib/ri_cal/property_value/cal_address.rb +11 -0
  71. data/lib/ri_cal/property_value/date.rb +184 -0
  72. data/lib/ri_cal/property_value/date_time/additive_methods.rb +44 -0
  73. data/lib/ri_cal/property_value/date_time/time_machine.rb +159 -0
  74. data/lib/ri_cal/property_value/date_time/timezone_support.rb +100 -0
  75. data/lib/ri_cal/property_value/date_time.rb +359 -0
  76. data/lib/ri_cal/property_value/duration.rb +110 -0
  77. data/lib/ri_cal/property_value/geo.rb +11 -0
  78. data/lib/ri_cal/property_value/integer.rb +12 -0
  79. data/lib/ri_cal/property_value/occurrence_list.rb +144 -0
  80. data/lib/ri_cal/property_value/period.rb +86 -0
  81. data/lib/ri_cal/property_value/recurrence_rule/enumeration_support_methods.rb +100 -0
  82. data/lib/ri_cal/property_value/recurrence_rule/enumerator.rb +79 -0
  83. data/lib/ri_cal/property_value/recurrence_rule/initialization_methods.rb +148 -0
  84. data/lib/ri_cal/property_value/recurrence_rule/negative_setpos_enumerator.rb +53 -0
  85. data/lib/ri_cal/property_value/recurrence_rule/numbered_span.rb +31 -0
  86. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_day_incrementer.rb +86 -0
  87. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_hour_incrementer.rb +31 -0
  88. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_minute_incrementer.rb +32 -0
  89. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_month_incrementer.rb +52 -0
  90. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_monthday_incrementer.rb +31 -0
  91. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_numbered_day_incrementer.rb +38 -0
  92. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_second_incrementer.rb +32 -0
  93. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_weekno_incrementer.rb +69 -0
  94. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/by_yearday_incrementer.rb +31 -0
  95. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/daily_incrementer.rb +28 -0
  96. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/frequency_incrementer.rb +80 -0
  97. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/hourly_incrementer.rb +23 -0
  98. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/list_incrementer.rb +106 -0
  99. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/minutely_incrementer.rb +23 -0
  100. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/monthly_incrementer.rb +33 -0
  101. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/null_sub_cycle_incrementer.rb +43 -0
  102. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/secondly_incrementer.rb +28 -0
  103. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/weekly_incrementer.rb +37 -0
  104. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer/yearly_incrementer.rb +57 -0
  105. data/lib/ri_cal/property_value/recurrence_rule/occurrence_incrementer.rb +135 -0
  106. data/lib/ri_cal/property_value/recurrence_rule/recurring_day.rb +131 -0
  107. data/lib/ri_cal/property_value/recurrence_rule/recurring_month_day.rb +64 -0
  108. data/lib/ri_cal/property_value/recurrence_rule/recurring_numbered_week.rb +33 -0
  109. data/lib/ri_cal/property_value/recurrence_rule/recurring_year_day.rb +53 -0
  110. data/lib/ri_cal/property_value/recurrence_rule/time_manipulation.rb +42 -0
  111. data/lib/ri_cal/property_value/recurrence_rule/validations.rb +125 -0
  112. data/lib/ri_cal/property_value/recurrence_rule.rb +154 -0
  113. data/lib/ri_cal/property_value/text.rb +44 -0
  114. data/lib/ri_cal/property_value/uri.rb +11 -0
  115. data/lib/ri_cal/property_value/utc_offset.rb +33 -0
  116. data/lib/ri_cal/property_value/zulu_date_time.rb +34 -0
  117. data/lib/ri_cal/property_value.rb +159 -0
  118. data/lib/ri_cal/required_timezones.rb +55 -0
  119. data/lib/ri_cal.rb +187 -0
  120. data/micahwedemeyer-ri_cal.gemspec +227 -0
  121. data/parked_specs/ri_cal/claudio_a_bug_spec.rb +100 -0
  122. data/performance/empty_propval/subject.rb +43 -0
  123. data/performance/paris_eastern/subject.rb +90 -0
  124. data/performance/penultimate_weekday/subject.rb +15 -0
  125. data/performance/psm_big_enum/ical.ics +3171 -0
  126. data/performance/psm_big_enum/subject.rb +16 -0
  127. data/performance/utah_cycling/subject.rb +55 -0
  128. data/sample_ical_files/from_ical_dot_app/test1.ics +38 -0
  129. data/script/benchmark_subject +23 -0
  130. data/script/console +10 -0
  131. data/script/destroy +14 -0
  132. data/script/generate +14 -0
  133. data/script/profile_subject +29 -0
  134. data/script/txt2html +71 -0
  135. data/spec/ri_cal/bugreports_spec.rb +287 -0
  136. data/spec/ri_cal/component/alarm_spec.rb +12 -0
  137. data/spec/ri_cal/component/calendar_spec.rb +88 -0
  138. data/spec/ri_cal/component/event_spec.rb +735 -0
  139. data/spec/ri_cal/component/freebusy_spec.rb +12 -0
  140. data/spec/ri_cal/component/journal_spec.rb +37 -0
  141. data/spec/ri_cal/component/t_z_info_timezone_spec.rb +60 -0
  142. data/spec/ri_cal/component/timezone_spec.rb +236 -0
  143. data/spec/ri_cal/component/todo_spec.rb +112 -0
  144. data/spec/ri_cal/component_spec.rb +224 -0
  145. data/spec/ri_cal/core_extensions/string/conversions_spec.rb +78 -0
  146. data/spec/ri_cal/core_extensions/time/calculations_spec.rb +188 -0
  147. data/spec/ri_cal/core_extensions/time/week_day_predicates_spec.rb +45 -0
  148. data/spec/ri_cal/fast_date_time_spec.rb +77 -0
  149. data/spec/ri_cal/inf_loop_spec.rb +78 -0
  150. data/spec/ri_cal/occurrence_enumerator_spec.rb +611 -0
  151. data/spec/ri_cal/parser_spec.rb +337 -0
  152. data/spec/ri_cal/property_value/date_spec.rb +53 -0
  153. data/spec/ri_cal/property_value/date_time_spec.rb +383 -0
  154. data/spec/ri_cal/property_value/duration_spec.rb +126 -0
  155. data/spec/ri_cal/property_value/occurrence_list_spec.rb +72 -0
  156. data/spec/ri_cal/property_value/period_spec.rb +63 -0
  157. data/spec/ri_cal/property_value/recurrence_rule/recurring_year_day_spec.rb +21 -0
  158. data/spec/ri_cal/property_value/recurrence_rule_spec.rb +1814 -0
  159. data/spec/ri_cal/property_value/text_spec.rb +25 -0
  160. data/spec/ri_cal/property_value/utc_offset_spec.rb +48 -0
  161. data/spec/ri_cal/property_value_spec.rb +125 -0
  162. data/spec/ri_cal/required_timezones_spec.rb +67 -0
  163. data/spec/ri_cal_spec.rb +53 -0
  164. data/spec/spec.opts +4 -0
  165. data/spec/spec_helper.rb +50 -0
  166. data/tasks/gem_loader/load_active_support.rb +3 -0
  167. data/tasks/gem_loader/load_tzinfo_gem.rb +2 -0
  168. data/tasks/ri_cal.rake +412 -0
  169. data/tasks/spec.rake +102 -0
  170. data/website/images/rubytrends.png +0 -0
  171. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  172. data/website/stylesheets/screen.css +159 -0
  173. metadata +307 -0
data/tasks/ri_cal.rake ADDED
@@ -0,0 +1,412 @@
1
+ #require 'active_support'
2
+ require 'yaml'
3
+ #- ©2009 Rick DeNatale, All rights reserved. Refer to the file README.txt for the license
4
+ #
5
+ # code stolen from ActiveSupport Gem
6
+ unless String.instance_methods.include?("camelize")
7
+ class String
8
+ def camelize
9
+ self.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
10
+ end
11
+ end
12
+ end
13
+
14
+ class VEntityUpdater
15
+ Pluralization = {
16
+ "attach" => "attachments",
17
+ "categories" => "multiple_categories",
18
+ "free_busy" => "free_busies",
19
+ "security_class" => "security_classes",
20
+ "request_status" => "request_statuses",
21
+ "related_to" => "multiple_related_to",
22
+ "resources" => "multiple_resources"
23
+ }
24
+ def initialize(target, defs_file)
25
+ @target = target
26
+ @name=File.basename(target).sub(".rb","")
27
+ @indent = ""
28
+ @property_map = {}
29
+ @property_defs = YAML.load_file(defs_file)
30
+ @all_props = {}
31
+ @date_time_props = []
32
+ end
33
+
34
+ def property(prop_name_or_hash)
35
+ if Hash === prop_name_or_hash
36
+ name = prop_name_or_hash.keys[0]
37
+ override_options = prop_name_or_hash[name] || {}
38
+ else
39
+ name = prop_name_or_hash
40
+ override_options = {}
41
+ end
42
+ standard_options = @property_defs[name]
43
+ unless standard_options
44
+ puts "**** WARNING, no definition found for property #{name}"
45
+ standard_options = {}
46
+ end
47
+ options = {'type' => 'Text', 'ruby_name' => name}.merge(standard_options).merge(override_options)
48
+ named_property(name, options)
49
+ end
50
+
51
+ def indent(string)
52
+ @outfile.puts("#{@indent}#{string}")
53
+ end
54
+
55
+ def comment(*strings)
56
+ strings.each do |string|
57
+ indent("\# #{string}")
58
+ end
59
+ end
60
+
61
+ def no_doc(string)
62
+ indent("#{string} \# :nodoc:")
63
+ end
64
+
65
+ def blank_line
66
+ @outfile.puts
67
+ end
68
+
69
+ def describe_type(type)
70
+ case type
71
+ when 'date_time_or_date'
72
+ "either DateTime or Date"
73
+ when 'Text'
74
+ 'String'
75
+ else
76
+ type
77
+ end
78
+ end
79
+
80
+ def describe_property(type)
81
+ case type
82
+ when 'date_time_or_date'
83
+ "either RiCal::PropertyValue::DateTime or RiCal::PropertyValue::Date"
84
+ else
85
+ "RiCal::PropertyValue#{type}"
86
+ end
87
+ end
88
+
89
+ def type_class(type)
90
+ if type == 'date_time_or_date'
91
+ "RiCal::PropertyValue::DateTime"
92
+ else
93
+ "RiCal::PropertyValue::#{type}"
94
+ end
95
+ end
96
+
97
+ def cast_value(ruby_val, type)
98
+ "#{type_class(type)}.convert(self, #{ruby_val.inspect})"
99
+ end
100
+
101
+ def lazy_init_var(var, options)
102
+ const_val = options["constant_value"]
103
+ default_val = options["default_value"]
104
+ if options["multi"]
105
+ puts("*** Warning default_value of #{default_val} for multi-value property #{name} ignored") if default_val
106
+ puts("*** Warning const_value of #{const_val} for multi-value property #{name} ignored") if const_val
107
+ if var
108
+ "@#{var} ||= []"
109
+ else
110
+ "[]"
111
+ end
112
+ else
113
+ puts("*** Warning default_value of #{default_val} for property #{name} with constant_value of #{const_val}") if const_val && default_val
114
+ init_val = const_val || default_val
115
+ if init_val
116
+ if var
117
+ "@#{var} ||= #{cast_value(init_val, options["type"])}"
118
+ else
119
+ init_val.inspect
120
+ end
121
+ else
122
+ "@#{var}"
123
+ end
124
+ end
125
+ end
126
+
127
+ def pluralize(name)
128
+ Pluralization[name] || "#{name}s"
129
+ end
130
+
131
+ def named_property(name, options)
132
+ ruby_name = options['ruby_name']
133
+ multi = options['multi']
134
+ type = options['type']
135
+ rfc_ref = options['rfc_ref']
136
+ conflicts = options['conflicts_with']
137
+ type_constraint = options['type_constraint']
138
+ options.keys.each do |opt_key|
139
+ unless %w{
140
+ ruby_name
141
+ type
142
+ multi
143
+ rfc_ref
144
+ conflicts_with
145
+ purpose
146
+ constant_value
147
+ default_value
148
+ }.include?(opt_key)
149
+ puts "**** WARNING: unprocessed option key #{opt_key} for property #{name}"
150
+ end
151
+ end
152
+ if conflicts
153
+ mutually_exclusive(name, *conflicts)
154
+ end
155
+ needs_tz_access = %w{OccurrenceList date_time_or_date DateTime Date}.include?(type)
156
+ ruby_name = ruby_name.tr("-", "_")
157
+ ruby_method = ruby_name.downcase
158
+ property = "#{name.tr("-", "_").downcase}_property"
159
+ if type_constraint != 'must_be_utc' && %w[date_time_or_date DateTime Period OccurrenceList].include?(type)
160
+ @date_time_props << property
161
+ end
162
+ @all_props[property] = name.upcase
163
+ @property_map[name.upcase] = :"#{property}_from_string"
164
+ parent_set = needs_tz_access ? " ? property_value.for_parent(self) : nil" : ""
165
+ if type == 'date_time_or_date'
166
+ line_evaluator = "RiCal::PropertyValue::DateTime.or_date(self, line)"
167
+ else
168
+ line_evaluator = "#{type_class(type)}.new(self, line)"
169
+ end
170
+
171
+ if %w{Array, OccurrenceList}.include?(type)
172
+ ruby_val_parm = "*ruby_value"
173
+ val_parm = "*val"
174
+ else
175
+ ruby_val_parm = "ruby_value"
176
+ val_parm = "val"
177
+ end
178
+ blank_line
179
+ if multi
180
+ comment(
181
+ "return the the #{name.upcase} property",
182
+ "which will be an array of instances of #{describe_property(type)}"
183
+ )
184
+ comment("", "[purpose (from RFC 2445)]", options["purpose"]) if options["purpose"]
185
+ comment("", "see RFC 2445 #{rfc_ref}") if rfc_ref
186
+ indent("def #{property}")
187
+ indent(" #{lazy_init_var(property,options)}")
188
+ indent("end")
189
+ unless (options["constant_value"])
190
+ plural_ruby_method = pluralize(ruby_method)
191
+ blank_line
192
+ comment("set the the #{name.upcase} property")
193
+ comment("one or more instances of #{describe_property(type)} may be passed to this method")
194
+ indent("def #{property}=(*property_values)")
195
+ if needs_tz_access
196
+ indent(" @#{property}= property_values.map{|prop| prop.for_parent(self)}")
197
+ else
198
+ indent(" @#{property}= property_values")
199
+ end
200
+ indent("end")
201
+ blank_line
202
+ comment("set the value of the #{name.upcase} property to multiple values")
203
+ comment("one or more instances of #{describe_type(type)} may be passed to this method")
204
+ indent("def #{plural_ruby_method}=(ruby_values)")
205
+ indent(" @#{property} = ruby_values.map {|val| #{type_class(type)}.convert(self, #{val_parm})}")
206
+ indent("end")
207
+ blank_line
208
+ comment("set the value of the #{name.upcase} property to a single value")
209
+ comment("one instance of #{describe_type(type)} may be passed to this method")
210
+ indent("def #{ruby_method}=(#{ruby_val_parm})")
211
+ indent(" @#{property} = [#{type_class(type)}.convert(self, #{ruby_val_parm})]")
212
+ indent("end")
213
+ blank_line
214
+ comment("add one or more values to the #{name.upcase} property")
215
+ comment("one or more instances of #{describe_type(type)} may be passed to this method")
216
+ indent("def add_#{plural_ruby_method}(*ruby_values)")
217
+ indent(" ruby_values.each {|val| self.#{property} << #{type_class(type)}.convert(self, #{val_parm})}")
218
+ indent("end")
219
+ blank_line
220
+ comment("add one value to the #{name.upcase} property")
221
+ comment("one instances of #{describe_type(type)} may be passed to this method")
222
+ indent("def add_#{ruby_method}(#{ruby_val_parm})")
223
+ indent(" self.#{property} << #{type_class(type)}.convert(self, #{ruby_val_parm})")
224
+ indent("end")
225
+ blank_line
226
+ comment("remove one or more values from the #{name.upcase} property")
227
+ comment("one or more instances of #{describe_type(type)} may be passed to this method")
228
+ indent("def remove_#{plural_ruby_method}(*ruby_values)")
229
+ indent(" ruby_values.each {|val| self.#{property}.delete(#{type_class(type)}.convert(self, #{val_parm}))}")
230
+ indent("end")
231
+ blank_line
232
+ comment("remove one value from the #{name.upcase} property")
233
+ comment("one instances of #{describe_type(type)} may be passed to this method")
234
+ indent("def remove_#{ruby_method}(#{ruby_val_parm})")
235
+ indent(" self.#{property}.delete(#{type_class(type)}.convert(self, #{ruby_val_parm}))")
236
+ indent("end")
237
+ end
238
+ blank_line
239
+ comment("return the value of the #{name.upcase} property")
240
+ comment("which will be an array of instances of #{describe_type(type)}")
241
+ indent("def #{ruby_method}")
242
+ indent(" #{property}.map {|prop| prop ? prop.ruby_value : prop}")
243
+ indent("end")
244
+ blank_line
245
+ no_doc("def #{property}_from_string(line)")
246
+ indent(" #{property} << #{line_evaluator}")
247
+ indent("end")
248
+ else
249
+ comment(
250
+ "return the the #{name.upcase} property",
251
+ "which will be an instances of #{describe_property(type)}"
252
+ )
253
+ comment("", "[purpose (from RFC 2445)]", options["purpose"]) if options["purpose"]
254
+ comment("", "see RFC 2445 #{rfc_ref}") if rfc_ref
255
+ indent("def #{property}")
256
+ indent(" #{lazy_init_var(property,options)}")
257
+ indent("end")
258
+ unless (options["constant_value"])
259
+ blank_line
260
+ comment("set the #{name.upcase} property")
261
+ comment("property value should be an instance of #{describe_property(type)}")
262
+ indent("def #{property}=(property_value)")
263
+ indent(" @#{property} = property_value#{parent_set}")
264
+ if conflicts
265
+ conflicts.each do |conflict|
266
+ indent(" @#{conflict}_property = nil")
267
+ end
268
+ end
269
+ indent("end")
270
+ blank_line
271
+ comment("set the value of the #{name.upcase} property")
272
+ indent("def #{ruby_method}=(ruby_value)")
273
+ indent(" self.#{property}= #{type_class(type)}.convert(self, ruby_value)")
274
+ indent("end")
275
+ end
276
+ blank_line
277
+ comment("return the value of the #{name.upcase} property")
278
+ comment("which will be an instance of #{describe_type(type)}")
279
+ indent("def #{ruby_method}")
280
+ indent(" #{property} ? #{property}.ruby_value : nil")
281
+ indent("end")
282
+ blank_line
283
+ no_doc("def #{property}_from_string(line)")
284
+ indent(" @#{property} = #{line_evaluator}")
285
+ indent("end")
286
+ @outfile.puts
287
+ end
288
+ end
289
+
290
+ def mutually_exclusive *prop_names
291
+ exclusives = prop_names.map {|str| :"#{str}_property"}.sort {|a, b| a.to_s <=> b.to_s}
292
+ unless mutually_exclusive_properties.include?(exclusives)
293
+ mutually_exclusive_properties << prop_names.map {|str| :"#{str}_property"}
294
+ end
295
+ end
296
+
297
+ def mutually_exclusive_properties
298
+ @mutually_exclusive_properties ||= []
299
+ end
300
+
301
+ def generate_support_methods
302
+ blank_line
303
+ indent("def export_properties_to(export_stream) #:nodoc:")
304
+ @all_props.each do |prop_attr, prop_name|
305
+ indent(" export_prop_to(export_stream, #{prop_name.inspect}, @#{prop_attr})")
306
+ end
307
+ indent("end")
308
+ blank_line
309
+ indent("def ==(o) #:nodoc:")
310
+ indent(" if o.class == self.class")
311
+ @all_props.keys.each_with_index do |prop_name, i|
312
+ and_str = i < @all_props.length - 1 ? " &&" : ""
313
+ indent(" (#{prop_name} == o.#{prop_name})#{and_str}")
314
+ end
315
+ indent(" else")
316
+ indent(" super")
317
+ indent(" end")
318
+ indent("end")
319
+ blank_line
320
+ indent("def initialize_copy(o) #:nodoc:")
321
+ indent(" super")
322
+ @all_props.each_key do |prop_name|
323
+ indent(" #{prop_name} = #{prop_name} && #{prop_name}.dup")
324
+ end
325
+ indent("end")
326
+ blank_line
327
+ indent("def add_date_times_to(required_timezones) #:nodoc:")
328
+ @date_time_props.each do | prop_name|
329
+ indent(" add_property_date_times_to(required_timezones, #{prop_name})")
330
+ end
331
+ indent("end")
332
+ blank_line
333
+ indent("module ClassMethods #:nodoc:")
334
+ indent(" def property_parser #:nodoc:")
335
+ indent(" #{@property_map.inspect}")
336
+ indent(" end")
337
+ indent("end")
338
+ blank_line
339
+ indent("def self.included(mod) #:nodoc:")
340
+ indent(" mod.extend ClassMethods")
341
+ indent("end")
342
+ blank_line
343
+ indent("def mutual_exclusion_violation #:nodoc:")
344
+ if mutually_exclusive_properties.empty?
345
+ indent(" false")
346
+ else
347
+ mutually_exclusive_properties.each do |mutex_set|
348
+ indent(" return true if #{mutex_set.inspect}.inject(0) {|sum, prop| send(prop) ? sum + 1 : sum} > 1")
349
+ end
350
+ indent(" false")
351
+ end
352
+ indent "end"
353
+ end
354
+
355
+ def update
356
+ File.open(File.join(File.dirname(__FILE__), '..', 'lib', 'ri_cal', 'properties' , "#{@name}.rb"), 'w') do |ruby_out_file|
357
+ @outfile = ruby_out_file
358
+ module_name = @name.camelize
359
+ class_name = module_name.sub(/Properties$/, "")
360
+ ruby_out_file.puts("module RiCal")
361
+ ruby_out_file.puts(" module Properties #:nodoc:")
362
+ @indent = " "
363
+ ruby_out_file.puts(" #- ©2009 Rick DeNatale")
364
+ ruby_out_file.puts(" #- All rights reserved. Refer to the file README.txt for the license")
365
+ ruby_out_file.puts(" #")
366
+ ruby_out_file.puts(" # Properties::#{module_name} provides property accessing methods for the #{class_name} class")
367
+ ruby_out_file.puts(" # This source file is generated by the rical:gen_propmodules rake tasks, DO NOT EDIT")
368
+ ruby_out_file.puts(" module #{module_name}")
369
+ @indent = " "
370
+ YAML.load_file(File.join(File.dirname(__FILE__), '..', 'component_attributes', "#{@name}.yml")).each do |att_def|
371
+ property(att_def)
372
+ end
373
+ generate_support_methods
374
+ ruby_out_file.puts(" end")
375
+ ruby_out_file.puts(" end")
376
+ ruby_out_file.puts("end")
377
+ end
378
+ @outfile = nil
379
+ end
380
+ end
381
+
382
+ def updateTask srcGlob, taskSymbol
383
+ targetDir = File.join(File.dirname(__FILE__), '..', 'lib', 'ri_cal', 'properties')
384
+ defsFile = File.join(File.dirname(__FILE__), '..', 'component_attributes', 'component_property_defs.yml')
385
+ FileList[srcGlob].each do |f|
386
+ unless f == defsFile
387
+ target = File.join targetDir, File.basename(f).gsub(".yml", ".rb")
388
+ file target => [f, defsFile, __FILE__] do |t|
389
+ VEntityUpdater.new(target, defsFile).update
390
+ end
391
+ task taskSymbol => target
392
+ end
393
+ end
394
+ end
395
+
396
+
397
+ namespace :rical do
398
+
399
+ desc '(RE)Generate VEntity attributes'
400
+ task :gen_propmodules do |t|
401
+ end
402
+
403
+ updateTask File.join(File.dirname(__FILE__), '..', '/component_attributes', '*.yml'), :gen_propmodules
404
+
405
+ end # namespace :rical
406
+
407
+ desc 'add or update copyright in code and specs'
408
+ task :copyrights do
409
+ require 'mmcopyrights'
410
+ MM::Copyrights.process('lib', "rb", "#-", IO.read('copyrights.txt'))
411
+ MM::Copyrights.process('spec', "rb", "#-", IO.read('copyrights.txt'))
412
+ end
data/tasks/spec.rake ADDED
@@ -0,0 +1,102 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run all specs"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ t.ruby_opts << "-rubygems"
22
+ end
23
+
24
+ namespace :spec do
25
+ desc "Run all specs in the presence of ActiveSupport"
26
+ Spec::Rake::SpecTask.new(:with_active_support) do |t|
27
+ t.spec_opts = ['--options', "spec/spec.opts"]
28
+ t.spec_files = FileList['spec/**/*_spec.rb']
29
+ t.ruby_opts << "-r #{File.join(File.dirname(__FILE__), *%w[gem_loader load_active_support])}"
30
+ end
31
+
32
+ desc "Run all specs in the presence of the tzinfo gem"
33
+ Spec::Rake::SpecTask.new(:with_tzinfo_gem) do |t|
34
+ t.spec_opts = ['--options', "spec/spec.opts"]
35
+ t.spec_files = FileList['spec/**/*_spec.rb']
36
+ t.ruby_opts << "-r #{File.join(File.dirname(__FILE__), *%w[gem_loader load_tzinfo_gem])}"
37
+ end
38
+ multiruby_path = `which multiruby`.chomp
39
+ if multiruby_path.length > 0 && Spec::Rake::SpecTask.instance_methods.include?("ruby_cmd")
40
+ namespace :multi do
41
+ desc "Run all specs with multiruby and ActiveSupport"
42
+ Spec::Rake::SpecTask.new(:with_active_support) do |t|
43
+ t.spec_opts = ['--options', "spec/spec.opts"]
44
+ t.spec_files = FileList['spec/**/*_spec.rb']
45
+ t.ruby_cmd = "#{multiruby_path}"
46
+ t.verbose = true
47
+ t.ruby_opts << "-r #{File.join(File.dirname(__FILE__), *%w[gem_loader load_active_support])}"
48
+ end
49
+
50
+ desc "Run all specs multiruby and the tzinfo gem"
51
+ Spec::Rake::SpecTask.new(:with_tzinfo_gem) do |t|
52
+ t.spec_opts = ['--options', "spec/spec.opts"]
53
+ t.spec_files = FileList['spec/**/*_spec.rb']
54
+ t.ruby_cmd = "#{multiruby_path}"
55
+ t.verbose = true
56
+ t.ruby_opts << "-r #{File.join(File.dirname(__FILE__), *%w[gem_loader load_tzinfo_gem])}"
57
+ end
58
+ end
59
+
60
+ desc "run all specs under multiruby with ActiveSupport and also with the tzinfo gem"
61
+ task :multi => [:"spec:multi:with_active_support", :"spec:multi:with_tzinfo_gem"]
62
+ end
63
+ end
64
+
65
+ if RUBY_VERSION.match(/^1\.8\./)
66
+ desc 'Run all specs with RCov'
67
+ Spec::Rake::SpecTask.new(:rcov) do |t|
68
+ t.spec_opts = ['--options', "spec/spec.opts"]
69
+ t.spec_files = FileList['spec/**/*_spec.rb']
70
+ t.rcov = true
71
+ t.rcov_dir = "coverage"
72
+ t.rcov_opts = ['--exclude', 'spec']
73
+ end
74
+ end
75
+
76
+ namespace :performance do
77
+ desc 'Run all benchmarks'
78
+ task :benchmark do
79
+ bench_script = File.join(File.dirname(__FILE__), '..', '/script', 'benchmark_subject')
80
+ bench_file = File.join(File.dirname(__FILE__), '..', '/performance_data', 'benchmarks.out')
81
+ cat = ">"
82
+ FileList[File.join(File.dirname(__FILE__), '..', '/performance', '*')].each do |f|
83
+ cmd = "#{bench_script} #{File.basename(f)} #{cat} #{bench_file}"
84
+ puts cmd
85
+ `#{cmd}`
86
+ cat = '>>'
87
+ end
88
+ end
89
+
90
+ desc 'Run all profiles'
91
+ task :profile do
92
+ bench_script = File.join(File.dirname(__FILE__), '..', '/script', 'profile_subject')
93
+ FileList[File.join(File.dirname(__FILE__), '..', '/performance', '*')].each do |f|
94
+ cmd = "#{bench_script} #{File.basename(f)}"
95
+ puts cmd
96
+ `#{cmd}`
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+
Binary file