actionpack 0.9.0 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (37) hide show
  1. data/CHANGELOG +88 -0
  2. data/README +2 -2
  3. data/RUNNING_UNIT_TESTS +12 -1
  4. data/install.rb +7 -3
  5. data/lib/action_controller.rb +2 -0
  6. data/lib/action_controller/assertions/action_pack_assertions.rb +39 -6
  7. data/lib/action_controller/base.rb +82 -49
  8. data/lib/action_controller/cgi_process.rb +3 -2
  9. data/lib/action_controller/helpers.rb +89 -0
  10. data/lib/action_controller/layout.rb +9 -3
  11. data/lib/action_controller/request.rb +7 -2
  12. data/lib/action_controller/response.rb +2 -2
  13. data/lib/action_controller/support/class_inheritable_attributes.rb +1 -1
  14. data/lib/action_controller/support/inflector.rb +8 -0
  15. data/lib/action_controller/test_process.rb +3 -2
  16. data/lib/action_controller/url_rewriter.rb +27 -11
  17. data/lib/action_view/base.rb +11 -0
  18. data/lib/action_view/helpers/active_record_helper.rb +5 -5
  19. data/lib/action_view/helpers/date_helper.rb +8 -1
  20. data/lib/action_view/helpers/form_helper.rb +12 -6
  21. data/lib/action_view/helpers/form_options_helper.rb +44 -1
  22. data/lib/action_view/helpers/text_helper.rb +13 -31
  23. data/lib/action_view/helpers/url_helper.rb +11 -5
  24. data/lib/action_view/partials.rb +5 -2
  25. data/rakefile +12 -3
  26. data/test/controller/action_pack_assertions_test.rb +30 -2
  27. data/test/controller/active_record_assertions_test.rb +2 -1
  28. data/test/controller/helper_test.rb +110 -0
  29. data/test/controller/send_file_test.rb +68 -0
  30. data/test/controller/url_test.rb +81 -35
  31. data/test/fixtures/helpers/abc_helper.rb +5 -0
  32. data/test/template/active_record_helper_test.rb +3 -3
  33. data/test/template/date_helper_test.rb +1 -0
  34. data/test/template/form_helper_test.rb +13 -6
  35. data/test/template/form_options_helper_test.rb +1 -1
  36. data/test/template/url_helper_test.rb +18 -4
  37. metadata +7 -2
@@ -71,7 +71,7 @@ module ActionController #:nodoc:
71
71
  @session["__valid_session"]
72
72
  return @session
73
73
  rescue ArgumentError => e
74
- @session.delete
74
+ @session.delete if @session
75
75
  raise(
76
76
  ActionController::SessionRestoreError,
77
77
  "Session contained objects where the class definition wasn't available. " +
@@ -104,6 +104,7 @@ module ActionController #:nodoc:
104
104
 
105
105
  def out
106
106
  convert_content_type!(@headers)
107
+ $stdout.binmode if $stdout.respond_to?(:binmode)
107
108
  print @cgi.header(@headers)
108
109
  if @body.respond_to?(:call)
109
110
  @body.call(self)
@@ -111,7 +112,7 @@ module ActionController #:nodoc:
111
112
  print @body
112
113
  end
113
114
  end
114
-
115
+
115
116
  private
116
117
  def convert_content_type!(headers)
117
118
  if headers["Content-Type"]
@@ -0,0 +1,89 @@
1
+ module ActionController #:nodoc:
2
+ module Helpers #:nodoc:
3
+ def self.append_features(base)
4
+ super
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ # The template helpers serves to relieve the templates from including the same inline code again and again. It's a
9
+ # set of standardized methods for working with forms (FormHelper), dates (DateHelper), texts (TextHelper), and
10
+ # Active Records (ActiveRecordHelper) that's available to all templates by default.
11
+ #
12
+ # It's also really easy to make your own helpers and it's much encouraged to keep the template files free
13
+ # from complicated logic. It's even encouraged to bundle common compositions of methods from other helpers
14
+ # (often the common helpers) as they're used by the specific application.
15
+ #
16
+ # module MyHelper
17
+ # def hello_world() "hello world" end
18
+ # end
19
+ #
20
+ # MyHelper can now be included in a controller, like this:
21
+ #
22
+ # class MyController < ActionController::Base
23
+ # helper :my_helper
24
+ # end
25
+ #
26
+ # ...and, same as above, used in any template rendered from MyController, like this:
27
+ #
28
+ # Let's hear what the helper has to say: <tt><%= hello_world %></tt>
29
+ module ClassMethods
30
+ # Makes all the (instance) methods in the helper module available to templates rendered through this controller.
31
+ # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
32
+ # available to the templates.
33
+ def add_template_helper(helper_module)
34
+ template_class.class_eval "include #{helper_module}"
35
+ end
36
+
37
+ # Declare a helper. If you use this method in your controller, you don't
38
+ # have to do the +self.append_features+ incantation in your helper class.
39
+ # helper :foo
40
+ # requires 'foo_helper' and includes FooHelper in the template class.
41
+ # helper FooHelper
42
+ # includes FooHelper in the template class.
43
+ # helper { def foo() "#{bar} is the very best" end }
44
+ # evaluates the block in the template class, adding method #foo.
45
+ # helper(:three, BlindHelper) { def mice() 'mice' end }
46
+ # does all three.
47
+ def helper(*args, &block)
48
+ args.flatten.each do |arg|
49
+ case arg
50
+ when Module
51
+ add_template_helper(arg)
52
+ when String, Symbol
53
+ file_name = Inflector.underscore(arg.to_s.downcase) + '_helper'
54
+ class_name = Inflector.camelize(file_name)
55
+ begin
56
+ require file_name
57
+ rescue LoadError
58
+ raise ArgumentError, "Missing helper file helpers/#{file_name}.rb"
59
+ end
60
+ raise ArgumentError, "Missing #{class_name} module in helpers/#{file_name}.rb" unless Object.const_defined?(class_name)
61
+ add_template_helper(Object.const_get(class_name))
62
+ else
63
+ raise ArgumentError, 'helper expects String, Symbol, or Module argument'
64
+ end
65
+ end
66
+
67
+ # Evaluate block in template class if given.
68
+ template_class.module_eval(&block) if block_given?
69
+ end
70
+
71
+ # Declare a controller method as a helper. For example,
72
+ # helper_method :link_to
73
+ # def link_to(name, options) ... end
74
+ # makes the link_to controller method available in the view.
75
+ def helper_method(*methods)
76
+ template_class.controller_delegate(*methods)
77
+ end
78
+
79
+ # Declare a controller attribute as a helper. For example,
80
+ # helper_attr :name
81
+ # attr_accessor :name
82
+ # makes the name and name= controller methods available in the view.
83
+ # The is a convenience wrapper for helper_method.
84
+ def helper_attr(*attrs)
85
+ attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
86
+ end
87
+ end
88
+ end
89
+ end
@@ -105,6 +105,12 @@ module ActionController #:nodoc:
105
105
  #
106
106
  # class WeblogController < ActionController::Base
107
107
  # layout "layouts/weblog_standard"
108
+ #
109
+ # == Avoiding the use of a layout
110
+ #
111
+ # If you have a layout that by default is applied to all the actions of a controller, you still have the option to rendering
112
+ # a given action without a layout. Just use the method <tt>render_without_layout</tt>, which works just like Base.render --
113
+ # it just doesn't apply any layouts.
108
114
  module ClassMethods
109
115
  # If a layout is specified, all actions rendered through render and render_action will have their result assigned
110
116
  # to <tt>@content_for_layout</tt>, which can then be used by the layout to insert their contents with
@@ -130,11 +136,11 @@ module ActionController #:nodoc:
130
136
  end
131
137
 
132
138
  def render_with_layout(template_name = "#{controller_name}/#{action_name}", status = nil, layout = nil) #:nodoc:
133
- if layout || active_layout
139
+ if layout ||= active_layout
134
140
  add_variables_to_assigns
135
- logger.info("Rendering #{template_name} within #{layout || active_layout}") unless logger.nil?
141
+ logger.info("Rendering #{template_name} within #{layout}") unless logger.nil?
136
142
  @content_for_layout = @template.render_file(template_name, true)
137
- render_without_layout(layout || self.active_layout, status)
143
+ render_without_layout(layout, status)
138
144
  else
139
145
  render_without_layout(template_name, status)
140
146
  end
@@ -1,5 +1,6 @@
1
1
  module ActionController
2
- class AbstractRequest #:nodoc:
2
+ # These methods are available in both the production and test Request objects.
3
+ class AbstractRequest
3
4
  # Returns both GET and POST parameters in a single hash.
4
5
  def parameters
5
6
  @parameters ||= request_parameters.update(query_parameters)
@@ -60,14 +61,18 @@ module ActionController
60
61
  end
61
62
 
62
63
  def host_with_port
63
- if (protocol == "http://" && port == 80) || (protocol == "https://" && port == 443)
64
+ if env['HTTP_HOST']
65
+ env['HTTP_HOST']
66
+ elsif (protocol == "http://" && port == 80) || (protocol == "https://" && port == 443)
64
67
  host
65
68
  else
66
69
  host + ":#{port}"
67
70
  end
68
71
  end
69
72
 
73
+ #--
70
74
  # Must be implemented in the concrete request
75
+ #++
71
76
  def query_parameters
72
77
  end
73
78
 
@@ -1,10 +1,10 @@
1
1
  module ActionController
2
2
  class AbstractResponse #:nodoc:
3
- DEFAULT_HEADERS = { "Cache-Control" => "no-cache", "cookie" => [] }
3
+ DEFAULT_HEADERS = { "Cache-Control" => "no-cache" }
4
4
  attr_accessor :body, :headers, :session, :cookies, :assigns, :template, :redirected_to, :redirected_to_method_params
5
5
 
6
6
  def initialize
7
- @body, @headers, @session, @assigns = "", DEFAULT_HEADERS.dup, [], []
7
+ @body, @headers, @session, @assigns = "", DEFAULT_HEADERS.merge("cookie" => []), [], []
8
8
  end
9
9
 
10
10
  def redirect(to_url)
@@ -1,4 +1,4 @@
1
- # Allows attributes to be shared within an inheritance hierarchy, but where each descentent gets a copy of
1
+ # Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
2
2
  # their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
3
3
  # to, for example, an array without those additions being shared with either their parent, siblings, or
4
4
  # children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
@@ -31,6 +31,14 @@ module Inflector
31
31
  class_name_in_module.gsub(/^.*::/, '')
32
32
  end
33
33
 
34
+ def tableize(class_name)
35
+ pluralize(underscore(class_name))
36
+ end
37
+
38
+ def classify(table_name)
39
+ camelize(singularize(table_name))
40
+ end
41
+
34
42
  def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
35
43
  Inflector.underscore(Inflector.demodulize(class_name)) +
36
44
  (separate_class_name_and_id_with_underscore ? "_id" : "id")
@@ -186,9 +186,10 @@ end
186
186
  class Test::Unit::TestCase #:nodoc:
187
187
  private
188
188
  # execute the request and set/volley the response
189
- def process(action, parameters = {})
189
+ def process(action, parameters = nil, session = nil)
190
190
  @request.action = action.to_s
191
- @request.parameters.update(parameters)
191
+ @request.parameters.update(parameters) unless parameters.nil?
192
+ @request.session = ActionController::TestSession.new(session) unless session.nil?
192
193
  @controller.process(@request, @response)
193
194
  end
194
195
  end
@@ -50,25 +50,41 @@ module ActionController
50
50
  path = rewrite_controller(path, options) if options[:controller] || options[:controller_prefix]
51
51
  return path
52
52
  end
53
-
53
+
54
54
  def rewrite_path_params(path, options)
55
- options[:path_params].inject(path) do |path, pair|
56
- if options[:action].nil? && @request.parameters[pair.first]
57
- path.sub(/\b#{@request.parameters[pair.first]}\b/, pair.last.to_s)
58
- else
59
- path += "/#{pair.last}"
55
+ index_action = options[:action] == 'index' || options[:action].nil? && @action == 'index'
56
+ id_only = options[:path_params].size == 1 && options[:path_params]['id']
57
+
58
+ if index_action && id_only
59
+ path += '/' unless path[-1..-1] == '/'
60
+ path += "index/#{options[:path_params]['id']}"
61
+ path
62
+ else
63
+ options[:path_params].inject(path) do |path, pair|
64
+ if options[:action].nil? && @request.parameters[pair.first]
65
+ path.sub(/\b#{@request.parameters[pair.first]}\b/, pair.last.to_s)
66
+ else
67
+ path += "/#{pair.last}"
68
+ end
60
69
  end
61
70
  end
62
71
  end
63
72
 
64
73
  def rewrite_action(path, options)
65
- all, controller_prefix, action_prefix, action_suffix =
74
+ # This regex assumes that "index" actions won't be included in the URL
75
+ all, controller_prefix, action_prefix, action_suffix =
66
76
  /^\/(.*)#{@controller}\/(.*)#{@action == "index" ? "" : @action}(.*)/.match(path).to_a
67
77
 
68
- if @action == "index" && action_prefix && !action_prefix.empty?
69
- path = path.sub(action_prefix, action_name(options, action_prefix))
70
- elsif @action == "index"
71
- path = path.sub(/#{@controller}\//, @controller + "/" + action_name(options))
78
+ if @action == "index"
79
+ if action_prefix == "index"
80
+ # we broke the parsing assumption that this would be excluded, so
81
+ # don't tell action_name about our little boo-boo
82
+ path = path.sub(action_prefix, action_name(options, nil))
83
+ elsif action_prefix && !action_prefix.empty?
84
+ path = path.sub(action_prefix, action_name(options, action_prefix))
85
+ else
86
+ path = path.sub(%r(#{@controller}/?), @controller + "/" + action_name(options)) # " ruby-mode
87
+ end
72
88
  else
73
89
  path = path.sub((action_prefix || "") + @action + (action_suffix || ""), action_name(options, action_prefix))
74
90
  end
@@ -141,6 +141,16 @@ module ActionView #:nodoc:
141
141
  end
142
142
  end
143
143
 
144
+ def self.controller_delegate(*methods)
145
+ methods.flatten.each do |method|
146
+ class_eval <<-end_eval
147
+ def #{method}(*args, &block)
148
+ controller.send(%(#{method}), *args, &block)
149
+ end
150
+ end_eval
151
+ end
152
+ end
153
+
144
154
  def initialize(base_path = nil, assigns_for_first_render = {}, controller = nil)#:nodoc:
145
155
  @base_path, @assigns = base_path, assigns_for_first_render
146
156
  @controller = controller
@@ -245,6 +255,7 @@ module ActionView #:nodoc:
245
255
  end
246
256
 
247
257
  def rxml_render(template, binding)
258
+ @controller.headers["Content-Type"] ||= 'text/xml'
248
259
  eval(template, binding)
249
260
  end
250
261
  end
@@ -26,11 +26,11 @@ module ActionView
26
26
  # form("post") =>
27
27
  # <form action='create' method='POST'>
28
28
  # <p>
29
- # <b>Title</b><br />
29
+ # <label for="post_title">Title</label><br />
30
30
  # <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />
31
31
  # </p>
32
32
  # <p>
33
- # <b>Body</b><br />
33
+ # <label for="post_body">Body</label><br />
34
34
  # <textarea cols="40" id="post_body" name="post[body]" rows="20" wrap="virtual">
35
35
  # Back to the hill and over it again!
36
36
  # </textarea>
@@ -71,8 +71,8 @@ module ActionView
71
71
  # <%= error_message_on "post", "title", "Title simply ", " (or it won't work)", "inputError" %> =>
72
72
  # <div class="inputError">Title simply can't be empty (or it won't work)</div>
73
73
  def error_message_on(object, method, prepend_text = "", append_text = "", css_class = "formError")
74
- if instance_eval("@#{object}").errors.on(method)
75
- "<div class=\"#{css_class}\">#{prepend_text + instance_eval("@#{object}").errors.on(method) + append_text}</div>"
74
+ if errors = instance_eval("@#{object}").errors.on(method)
75
+ "<div class=\"#{css_class}\">#{prepend_text + (errors.is_a?(Array) ? errors.first : errors) + append_text}</div>"
76
76
  end
77
77
  end
78
78
 
@@ -94,7 +94,7 @@ module ActionView
94
94
  end
95
95
 
96
96
  def default_input_block
97
- Proc.new { |record, column| "<p><b>#{column.human_name}</b><br />#{input(record, column.name)}</p>" }
97
+ Proc.new { |record, column| "<p><label for=\"#{record}_#{column.name}\">#{column.human_name}</label><br />#{input(record, column.name)}</p>" }
98
98
  end
99
99
  end
100
100
 
@@ -19,13 +19,20 @@ module ActionView
19
19
  distance_in_minutes = ((to_time - from_time) / 60).round
20
20
 
21
21
  case distance_in_minutes
22
- when 0..45 then "#{distance_in_minutes} minutes"
22
+ when 0 then "less than a minute"
23
+ when 1 then "1 minute"
24
+ when 2..45 then "#{distance_in_minutes} minutes"
23
25
  when 46..90 then "about 1 hour"
24
26
  when 90..1440 then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
25
27
  when 1441..2880 then "1 day"
26
28
  else "#{(distance_in_minutes / 1440).round} days"
27
29
  end
28
30
  end
31
+
32
+ # Like distance_of_time_in_words, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
33
+ def distance_of_time_in_words_to_now(from_time)
34
+ distance_of_time_in_words(from_time, Time.now)
35
+ end
29
36
 
30
37
  # Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute (identified by
31
38
  # +method+) on an object assigned to the template (identified by +object+). It's possible to tailor the selects through the +options+ hash,
@@ -85,13 +85,19 @@ module ActionView
85
85
  # Returns a checkbox tag tailored for accessing a specified attribute (identified by +method+) on an object
86
86
  # assigned to the template (identified by +object+). It's intended that +method+ returns an integer and if that
87
87
  # integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a
88
- # hash with +options+. The +value+ defaults to 1, which is convenient for boolean values.
88
+ # hash with +options+. The +checked_value+ defaults to 1 while the default +unchecked_value+
89
+ # is set to 0 which is convenient for boolean values. Usually unchecked checkboxes don't post anything.
90
+ # We work around this problem by adding a hidden value with the same name as the checkbox.
89
91
  #
90
92
  # Example (call, result). Imagine that @post.validated? returns 1:
91
93
  # check_box("post", "validated")
92
- # <input type="checkbox" id="post_validate" name="post[validated] value="1" checked="checked" />
93
- def check_box(object, method, options = {}, value = "1")
94
- InstanceTag.new(object, method, self).to_check_box_tag(options, value)
94
+ # <input type="checkbox" id="post_validate" name="post[validated] value="1" checked="checked" /><input name="post[validated]" type="hidden" value="0" />
95
+ #
96
+ # Example (call, result). Imagine that @puppy.gooddog returns no:
97
+ # check_box("puppy", "gooddog", {}, "yes", "no")
98
+ # <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog] value="yes" /><input name="puppy[gooddog]" type="hidden" value="no" />
99
+ def check_box(object, method, options = {}, checked_value = "1", unchecked_value = "0")
100
+ InstanceTag.new(object, method, self).to_check_box_tag(options, checked_value, unchecked_value)
95
101
  end
96
102
  end
97
103
 
@@ -122,11 +128,11 @@ module ActionView
122
128
  content_tag("textarea", html_escape(value), options)
123
129
  end
124
130
 
125
- def to_check_box_tag(options = {}, checked_value = "1")
131
+ def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0")
126
132
  options.merge!({"checked" => "checked"}) if !value.nil? && ((value.is_a?(TrueClass) || value.is_a?(FalseClass)) ? value : value.to_i > 0)
127
133
  options.merge!({ "type" => "checkbox", "value" => checked_value })
128
134
  add_default_name_and_id(options)
129
- tag("input", options)
135
+ tag("input", options) << tag("input", ({ "name" => options['name'], "type" => "hidden", "value" => unchecked_value }))
130
136
  end
131
137
 
132
138
  def to_date_tag()
@@ -137,7 +137,50 @@ module ActionView
137
137
 
138
138
  private
139
139
  # All the countries included in the country_options output.
140
- COUNTRIES = [ "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica", "Antigua And Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegowina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", "Congo, the Democratic Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "East Timor", "Ecuador", "Egypt", "El Salvador", "England", "Equatorial Guinea", "Eritrea", "Espana", "Estonia", "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France", "French Guiana", "French Polynesia", "French Southern Territories", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Great Britain", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana", "Haiti", "Heard and Mc Donald Islands", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Ireland", "Israel", "Italy", "Jamaica", "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, Republic of", "Korea (South)", "Kuwait", "Kyrgyzstan", "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", "Liberia", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia, Federated States of", "Moldova, Republic of", "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "Northern Ireland", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russia", "Russian Federation", "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Vincent and the Grenadines", "Samoa (Independent)", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Scotland", "Senegal", "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea", "Spain", "Sri Lanka", "St. Helena", "St. Pierre and Miquelon", "Suriname", "Svalbard and Jan Mayen Islands", "Swaziland", "Sweden", "Switzerland", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Togo", "Tokelau", "Tonga", "Trinidad", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu", "Vatican City State (Holy See)", "Venezuela", "Viet Nam", "Virgin Islands (British)", "Virgin Islands (U.S.)", "Wales", "Wallis and Futuna Islands", "Western Sahara", "Yemen", "Zambia", "Zimbabwe" ] unless const_defined?("COUNTRIES")
140
+ COUNTRIES = [ "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla",
141
+ "Antarctica", "Antigua And Barbuda", "Argentina", "Armenia", "Aruba", "Australia",
142
+ "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus",
143
+ "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegowina",
144
+ "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
145
+ "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cambodia",
146
+ "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic",
147
+ "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia",
148
+ "Comoros", "Congo", "Congo, the Democratic Republic of the", "Cook Islands",
149
+ "Costa Rica", "Cote d'Ivoire", "Croatia", "Cyprus", "Czech Republic", "Denmark",
150
+ "Djibouti", "Dominica", "Dominican Republic", "East Timor", "Ecuador", "Egypt",
151
+ "El Salvador", "England", "Equatorial Guinea", "Eritrea", "Espana", "Estonia",
152
+ "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France",
153
+ "French Guiana", "French Polynesia", "French Southern Territories", "Gabon", "Gambia",
154
+ "Georgia", "Germany", "Ghana", "Gibraltar", "Great Britain", "Greece", "Greenland",
155
+ "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", "Guyana",
156
+ "Haiti", "Heard and Mc Donald Islands", "Honduras", "Hong Kong", "Hungary", "Iceland",
157
+ "India", "Indonesia", "Ireland", "Israel", "Italy", "Jamaica", "Japan", "Jordan",
158
+ "Kazakhstan", "Kenya", "Kiribati", "Korea, Republic of", "Korea (South)", "Kuwait",
159
+ "Kyrgyzstan", "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho",
160
+ "Liberia", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia",
161
+ "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
162
+ "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico",
163
+ "Micronesia, Federated States of", "Moldova, Republic of", "Monaco", "Mongolia",
164
+ "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal",
165
+ "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua",
166
+ "Niger", "Nigeria", "Niue", "Norfolk Island", "Northern Ireland",
167
+ "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama",
168
+ "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Pitcairn", "Poland",
169
+ "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russia", "Rwanda",
170
+ "Saint Kitts and Nevis", "Saint Lucia", "Saint Vincent and the Grenadines",
171
+ "Samoa (Independent)", "San Marino", "Sao Tome and Principe", "Saudi Arabia",
172
+ "Scotland", "Senegal", "Seychelles", "Sierra Leone", "Singapore", "Slovakia",
173
+ "Slovenia", "Solomon Islands", "Somalia", "South Africa",
174
+ "South Georgia and the South Sandwich Islands", "South Korea", "Spain", "Sri Lanka",
175
+ "St. Helena", "St. Pierre and Miquelon", "Suriname", "Svalbard and Jan Mayen Islands",
176
+ "Swaziland", "Sweden", "Switzerland", "Taiwan", "Tajikistan", "Tanzania", "Thailand",
177
+ "Togo", "Tokelau", "Tonga", "Trinidad", "Trinidad and Tobago", "Tunisia", "Turkey",
178
+ "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine",
179
+ "United Arab Emirates", "United Kingdom", "United States",
180
+ "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu",
181
+ "Vatican City State (Holy See)", "Venezuela", "Viet Nam", "Virgin Islands (British)",
182
+ "Virgin Islands (U.S.)", "Wales", "Wallis and Futuna Islands", "Western Sahara",
183
+ "Yemen", "Zambia", "Zimbabwe" ] unless const_defined?("COUNTRIES")
141
184
  end
142
185
 
143
186
  class InstanceTag #:nodoc: