sinatra-helpers 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -19,3 +19,6 @@ rdoc
19
19
  pkg
20
20
 
21
21
  ## PROJECT::SPECIFIC
22
+ /.yardoc
23
+ /doc
24
+ /.rvmrc
@@ -0,0 +1,58 @@
1
+ Sinatra Helpers: a common collection of useful utilities
2
+ --------------------------------------------------------
3
+
4
+ Bare minimum, close to the metal helpers for your average sinatra application.
5
+ Read the full documentation at [http://labs.sinefunc.com/sinatra-helpers/doc](http://labs.sinefunc.com/sinatra-helpers/doc).
6
+
7
+ Defines...
8
+ ----------
9
+
10
+ # from a Sinatra context point of view...
11
+ set :default_year_loffset, -60
12
+ set :default_year_uoffset, 0
13
+ set :default_month_names, Date::MONTHNAMES
14
+
15
+ set :default_currency_unit, '$'
16
+ set :default_currency_precision, 2
17
+ set :default_currency_separator, ','
18
+
19
+ Examples
20
+ --------
21
+
22
+ # what are helpers for if you don't have `h` ^_^
23
+ =h "<Bar>"
24
+
25
+ %select(name='country')
26
+ != country_choices
27
+
28
+ %select(name='birthday[month'])
29
+ != month_choices
30
+
31
+ %select(name='birthday[day]')
32
+ != day_choices
33
+
34
+ %select(name='birthday[year'])
35
+ != year_choices
36
+
37
+ %select(name="categories")
38
+ != select_options [['First', 1], ['Second', 2]]
39
+
40
+ = currency(100)
41
+ -# displays $ 100.00
42
+
43
+ = percentage(100)
44
+ -# displays 100.00%
45
+
46
+ # If you have an ohm model which you want to present the errors of:
47
+ # (this is taken from the reddit-clone courtesy of citrusbyte)
48
+
49
+ # This should be put in your HAML file
50
+
51
+ - errors_on @user do |e|
52
+ - e.on [:email, :not_present] "You must supply an email address"
53
+ - e.on [:password, :not_present] "A password is required"
54
+ - e.on [:password, :not_confirmed] "You must confirm your password"
55
+
56
+ ### Copyright
57
+
58
+ Copyright (c) 2010 Cyril David. See LICENSE for details.
data/Rakefile CHANGED
@@ -10,7 +10,13 @@ begin
10
10
  gem.email = "cyx.ucron@gmail.com"
11
11
  gem.homepage = "http://github.com/sinefunc/sinatra-helpers"
12
12
  gem.authors = ["Cyril David"]
13
+ gem.add_dependency "sinatra", ">= 1.0"
13
14
  gem.add_development_dependency "contest", ">= 0"
15
+ gem.add_development_dependency "mocha", ">= 0"
16
+ gem.add_development_dependency "rack-test", ">= 0"
17
+ gem.add_development_dependency "nokogiri", ">= 0"
18
+ gem.add_development_dependency "ohm", ">= 0"
19
+ gem.add_development_dependency "haml", ">= 0"
14
20
  end
15
21
  Jeweler::GemcutterTasks.new
16
22
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
@@ -1,32 +1,163 @@
1
1
  require 'date'
2
+ require 'sinatra/base'
2
3
  require 'sinatra/helpers/compat-1.8.6'
3
4
 
4
5
  module Sinatra
5
6
  module Helpers
7
+ VERSION = "0.2.0"
8
+
6
9
  autoload :HamlErrorPresenter, "sinatra/helpers/haml_error_presenter"
7
10
  autoload :Country, "sinatra/helpers/country"
11
+
12
+ # @private Sinatra extension writing style.
13
+ # @see http://www.sinatrarb.com/extensions.html#setting_options_and_other_extension_setup
14
+ def self.registered(app)
15
+ app.set :default_year_loffset, -60
16
+ app.set :default_year_uoffset, 0
17
+ app.set :default_month_names, Date::MONTHNAMES
18
+
19
+ app.set :default_currency_unit, '$'
20
+ app.set :default_currency_precision, 2
21
+ app.set :default_currency_separator, ','
22
+ end
23
+
24
+ # Returns an HTML sanitized string.
25
+ def h(str)
26
+ Rack::Utils.escape_html(str)
27
+ end
8
28
 
29
+ # Returns an array of pairs i.e.
30
+ #
31
+ # - ["Afghanistan", "AF"]
32
+ # - ...
33
+ # - ["United States", "US"]
34
+ # - ...
35
+ # - ["Zimbabwe", "ZW"]
36
+ #
37
+ # @return [Array] the array of name, code pairs.
9
38
  def country_choices
10
39
  Country.to_select
11
40
  end
12
-
13
- def month_choices
14
- Date::MONTHNAMES.map.
15
- with_index { |month, idx| ["%d - %s" % [idx, month], idx] }.
41
+
42
+ # Returns an array of pairs i.e.
43
+ #
44
+ # - [1, 1]
45
+ # - [2, 2]
46
+ # - ...
47
+ # - [31, 31]
48
+ #
49
+ # @return [Array] the array of day, day pairs.
50
+ def day_choices
51
+ days = (1..31).to_a
52
+ days.zip(days)
53
+ end
54
+
55
+ # Returns an array of pairs i.e.
56
+ # - ['January', 1]
57
+ # - ['February', 2]
58
+ # - ...
59
+ # - ['December', 12]
60
+ #
61
+ # You may pass in Date::ABBR_MONTHNAMES if you want the shortened month names.
62
+ #
63
+ # @param [Array] month_names (defaults to Date::MONTHNAMES) an array with the
64
+ # first element being nil, element 1 being January, etc.
65
+ # @return [Array] the array of month name, month pairs.
66
+ def month_choices(month_names = settings.default_month_names)
67
+ month_names.map.
68
+ with_index { |month, idx| [month, idx] }.
16
69
  tap { |arr| arr.shift }
17
70
  end
18
-
19
- def year_choices(loffset = -20, uoffset = +20)
71
+
72
+ # Returns an array of pairs i.e.
73
+ # - [2005, 2005]
74
+ # - [2006, 2006]
75
+ # - ...
76
+ # - [2010, 2010]
77
+ #
78
+ # @example
79
+ #
80
+ # year_choices # assuming it's now 2010
81
+ # # => [[1950, 1950], ..., [2010, 2010]]
82
+ #
83
+ # # we can pass in options
84
+ # year_choices(0, 6) # like for credit card options
85
+ # # => [[2010, 2010], ..., [2016, 2016]]
86
+ #
87
+ # # also we can override settings at the app level
88
+ # set :default_year_loffset, 0
89
+ # set :default_year_uoffset, 6
90
+ # year_choices
91
+ # # => [[2010, 2010], ..., [2016, 2016]]
92
+ #
93
+ # @param [Fixnum] loffset (defaults to -60) The lower offset relative to the current year.
94
+ # If it's 2010 now, passing in -5 here will start the year
95
+ # list at 2005 for example.
96
+ # @param [Fixnum] uoffset (defaults to 0) The upper offset relative to the
97
+ # current year. If it's 2010 now, passing in 5 or +5 here
98
+ # will end the year list at 2015 for example.
99
+ # @return [Array] the array of year, year pairs.
100
+ def year_choices(loffset = settings.default_year_loffset, uoffset = settings.default_year_uoffset)
20
101
  years = ((Date.today.year + loffset)..(Date.today.year + uoffset)).to_a
21
102
  years.zip(years)
22
103
  end
104
+
105
+ # Accepts a list of pairs and produces option tags.
106
+ #
107
+ # @example
108
+ #
109
+ # select_options([['One', 1], ['Two', 2]])
110
+ # select_options([['One', 1], ['Two', 2]], 1)
111
+ # select_options([['One', 1], ['Two', 2]], 1, '- Choose -')
112
+ #
113
+ # # using it with the provided date helpers...
114
+ # select_options year_choices, 2010 # select 2010 as default
115
+ # select_options month_choices, 5 # select May as default
116
+ # select_options day_choices, 25 # select the 25th as default
117
+ #
118
+ # @param [Array] pairs a collection of label, value tuples.
119
+ # @param [Object] current the current value of this select.
120
+ # @param [#to_s] prompt a default prompt to place at the beginning
121
+ # of the list.
122
+ def select_options(pairs, current = nil, prompt = nil)
123
+ pairs.unshift([prompt, '']) if prompt
23
124
 
24
- def select_options(pairs, current)
25
125
  pairs.map { |label, value|
26
126
  tag(:option, label, :value => value, :selected => (current == value))
27
127
  }.join("\n")
28
128
  end
29
-
129
+
130
+ # Presents errors on your form. Takes the explicit approach and assumes
131
+ # that for every form you have, the copy for the errors are important,
132
+ # instead of producing canned responses.
133
+ #
134
+ # Allows you to do the following in your haml view:
135
+ #
136
+ # @example
137
+ #
138
+ # - errors_on @user do |e|
139
+ # - e.on [:email, :not_present], "We need your email address."
140
+ # - e.on [:password, :not_present], "You must specify a password."
141
+ #
142
+ # # produces the following:
143
+ # # <div class="errors">
144
+ # # <ul>
145
+ # # <li>We need your email address</li>
146
+ # # <li>You must specify a password.</li>
147
+ # # </ul>
148
+ # # </div>
149
+ #
150
+ # @param [#errors] object An object responding to #errors. This validation
151
+ # also checks for the presence of a #full_messages method
152
+ # in the errors object for compatibility with ActiveRecord
153
+ # style objects.
154
+ # @param [Hash] options a hash of HTML attributes to place on the
155
+ # containing div.
156
+ # @option options [#to_s] :class (defaults to errors) The css class to put
157
+ # in the div.
158
+ # @yield [Sinatra::Helpers::HamlErrorPresenter] an object responding to #on.
159
+ #
160
+ # @see Sinatra::Helpers::HamlErrorPresenter#on
30
161
  def errors_on(object, options = { :class => 'errors' }, &block)
31
162
  return if object.errors.empty?
32
163
 
@@ -44,15 +175,81 @@ module Sinatra
44
175
  end
45
176
  end
46
177
  end
47
-
178
+
179
+ # Formats a number into a currency display. Uses the following settings:
180
+ #
181
+ # - settings.default_currency_unit (defaults to '$')
182
+ # - settings.default_currency_precision (defaults to 2)
183
+ # - settings.default_currenty_separator (defaults to ',')
184
+ #
185
+ # @example
186
+ #
187
+ # currency(100) == "$ 100.00"
188
+ # # => true
189
+ #
190
+ # currency(100, :unit => "&pound;") == "&pound; 100.00"
191
+ # # => true
192
+ #
193
+ # currency(100, :precision => 0) == "$ 100"
194
+ # => # true
195
+ #
196
+ # # somewhere in your sinatra context after registering Sinatra::Helpers
197
+ # set :default_currency_unit, '&pound;'
198
+ # set :default_currency_precision, 3
199
+ # set :default_currency_separator, ' '
200
+ #
201
+ # currency(100) == "&pound; 100.000"
202
+ # # => true
203
+ #
204
+ # @param [Numeric] number the number you wish to display as a currency.
205
+ # @param [Hash] opts the various options available.
206
+ # @option opts [#to_s] :unit (defaults to '$')
207
+ # @option opts [Fixnum] :precision (defaults to 2)
208
+ # @option opts [#to_s] :separator (defaults to ',')
209
+ # @return [String] the formatted string based on `number`.
210
+ # @return [nil] if given nil or an empty string.
211
+ def currency(number, opts = {})
212
+ return if number.to_s.empty?
213
+
214
+ unit = opts[:unit] || settings.default_currency_unit
215
+ precision = opts[:precision] || settings.default_currency_precision
216
+ separator = opts[:separator] || settings.default_currency_separator
217
+
218
+ ret = "%s %.#{ Integer(precision) }f" % [unit, number]
219
+ parts = ret.split('.')
220
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{separator}")
221
+ parts.join('.')
222
+ end
223
+
224
+ # Show the percentage representation of a numeric value.
225
+ #
226
+ # @example
227
+ # percentage(100) == "100.00%"
228
+ # percentage(100, 0) == "100%"
229
+ #
230
+ # @param [Numeric] number A numeric value
231
+ # @param [Fixnum] precision (defaults to 2) Number of decimals to show.
232
+ # @return [String] the number displayed as a percentage
233
+ # @return [nil] given a nil value or an empty string.
234
+ def percentage(number, precision = 2)
235
+ return if number.to_s.empty?
236
+
237
+ ret = "%02.#{ precision }f%" % number
238
+ ret.gsub(/\.0*%$/, '%')
239
+ end
240
+
48
241
  protected
49
242
  def tag(tag, content, atts = {})
50
- tag_atts = atts.inject("") { |a, (k, v)|
51
- a << ('%s="%s"' % [k, v]) if v
243
+ tag_atts = atts.inject([]) { |a, (k, v)|
244
+ a << (' %s="%s"' % [k, escape_attr(v)]) if v
52
245
  a
53
- }
246
+ }.join('')
247
+
248
+ %(<#{ tag }#{ tag_atts }>#{h content}</#{ tag }>)
249
+ end
54
250
 
55
- %(<#{ tag } #{ tag_atts }>#{ content }</#{ tag }>)
251
+ def escape_attr(str)
252
+ str.to_s.gsub("'", "&#39;").gsub('"', "&quot;")
56
253
  end
57
254
  end
58
255
 
@@ -1,8 +1,9 @@
1
1
  # Taken from ohm
2
2
 
3
3
  unless "".respond_to?(:lines)
4
+ # @private 1.8.6 compatibility only
4
5
  class String
5
-
6
+ # @private
6
7
  # This version of String#lines is almost fully compatible with that
7
8
  # of Ruby 1.9. If a zero-length record separator is supplied in Ruby
8
9
  # 1.9, the string is split into paragraphs delimited by multiple
@@ -17,11 +18,13 @@ unless "".respond_to?(:lines)
17
18
  end
18
19
 
19
20
  unless respond_to?(:tap)
21
+ # @private 1.8.6 compatibility only
20
22
  class Object
23
+ # @private no need to explain. Standard ruby 1.9 stuff.
24
+ # @see http://ruby-doc.org/ruby-1.9/classes/Object.html#M000239
21
25
  def tap
22
26
  yield(self)
23
27
  self
24
28
  end
25
29
  end
26
30
  end
27
-
@@ -2,10 +2,11 @@
2
2
 
3
3
  module Sinatra
4
4
  module Helpers
5
- class Country
6
- LOOKUP = {
5
+ # A simple module containing all countries as of 2010.
6
+ module Country
7
+ @all = {
7
8
  :AF => "Afghanistan",
8
- :AX => "Aland Islands",
9
+ :AX => "Åland Islands",
9
10
  :AL => "Albania",
10
11
  :DZ => "Algeria",
11
12
  :AS => "American Samoa",
@@ -30,22 +31,19 @@ module Sinatra
30
31
  :BJ => "Benin",
31
32
  :BM => "Bermuda",
32
33
  :BT => "Bhutan",
33
- :BO => "Bolivia",
34
+ :BO => "Bolivia, Plurinational State of",
34
35
  :BA => "Bosnia and Herzegovina",
35
36
  :BW => "Botswana",
36
37
  :BV => "Bouvet Island",
37
38
  :BR => "Brazil",
38
- :BQ => "British Antarctic Territory",
39
39
  :IO => "British Indian Ocean Territory",
40
- :VG => "British Virgin Islands",
41
- :BN => "Brunei",
40
+ :BN => "Brunei Darussalam",
42
41
  :BG => "Bulgaria",
43
42
  :BF => "Burkina Faso",
44
43
  :BI => "Burundi",
45
44
  :KH => "Cambodia",
46
45
  :CM => "Cameroon",
47
46
  :CA => "Canada",
48
- :CT => "Canton and Enderbury Islands",
49
47
  :CV => "Cape Verde",
50
48
  :KY => "Cayman Islands",
51
49
  :CF => "Central African Republic",
@@ -53,13 +51,14 @@ module Sinatra
53
51
  :CL => "Chile",
54
52
  :CN => "China",
55
53
  :CX => "Christmas Island",
56
- :CC => "Cocos Islands",
54
+ :CC => "Cocos (Keeling) Islands",
57
55
  :CO => "Colombia",
58
56
  :KM => "Comoros",
59
- :CG => "Congo - Brazzaville",
60
- :CD => "Congo - Kinshasa",
57
+ :CG => "Congo",
58
+ :CD => "Congo, the Democratic Republic of the",
61
59
  :CK => "Cook Islands",
62
60
  :CR => "Costa Rica",
61
+ :CI => "CÔte D'ivoire",
63
62
  :HR => "Croatia",
64
63
  :CU => "Cuba",
65
64
  :CY => "Cyprus",
@@ -68,9 +67,6 @@ module Sinatra
68
67
  :DJ => "Djibouti",
69
68
  :DM => "Dominica",
70
69
  :DO => "Dominican Republic",
71
- :NQ => "Dronning Maud Land",
72
- :DD => "East Germany",
73
- :TL => "East Timor",
74
70
  :EC => "Ecuador",
75
71
  :EG => "Egypt",
76
72
  :SV => "El Salvador",
@@ -78,8 +74,7 @@ module Sinatra
78
74
  :ER => "Eritrea",
79
75
  :EE => "Estonia",
80
76
  :ET => "Ethiopia",
81
- :QU => "European Union",
82
- :FK => "Falkland Islands",
77
+ :FK => "Falkland Islands (Malvinas)",
83
78
  :FO => "Faroe Islands",
84
79
  :FJ => "Fiji",
85
80
  :FI => "Finland",
@@ -87,7 +82,6 @@ module Sinatra
87
82
  :GF => "French Guiana",
88
83
  :PF => "French Polynesia",
89
84
  :TF => "French Southern Territories",
90
- :FQ => "French Southern and Antarctic Territories",
91
85
  :GA => "Gabon",
92
86
  :GM => "Gambia",
93
87
  :GE => "Georgia",
@@ -102,44 +96,45 @@ module Sinatra
102
96
  :GT => "Guatemala",
103
97
  :GG => "Guernsey",
104
98
  :GN => "Guinea",
105
- :GW => "Guinea-Bissau",
99
+ :GW => "Guinea-bissau",
106
100
  :GY => "Guyana",
107
101
  :HT => "Haiti",
108
- :HM => "Heard Island and McDonald Islands",
102
+ :HM => "Heard Island and Mcdonald Islands",
103
+ :VA => "Holy See (Vatican City State)",
109
104
  :HN => "Honduras",
110
105
  :HK => "Hong Kong",
111
106
  :HU => "Hungary",
112
107
  :IS => "Iceland",
113
108
  :IN => "India",
114
109
  :ID => "Indonesia",
115
- :IR => "Iran",
110
+ :IR => "Iran, Islamic Republic of",
116
111
  :IQ => "Iraq",
117
112
  :IE => "Ireland",
118
113
  :IM => "Isle of Man",
119
114
  :IL => "Israel",
120
115
  :IT => "Italy",
121
- :CI => "Ivory Coast",
122
116
  :JM => "Jamaica",
123
117
  :JP => "Japan",
124
118
  :JE => "Jersey",
125
- :JT => "Johnston Island",
126
119
  :JO => "Jordan",
127
120
  :KZ => "Kazakhstan",
128
121
  :KE => "Kenya",
129
122
  :KI => "Kiribati",
123
+ :KP => "Korea, Democratic People's Republic of",
124
+ :KR => "Korea, Republic of",
130
125
  :KW => "Kuwait",
131
126
  :KG => "Kyrgyzstan",
132
- :LA => "Laos",
127
+ :LA => "Lao People's Democratic Republic",
133
128
  :LV => "Latvia",
134
129
  :LB => "Lebanon",
135
130
  :LS => "Lesotho",
136
131
  :LR => "Liberia",
137
- :LY => "Libya",
132
+ :LY => "Libyan Arab Jamahiriya",
138
133
  :LI => "Liechtenstein",
139
134
  :LT => "Lithuania",
140
135
  :LU => "Luxembourg",
141
- :MO => "Macau",
142
- :MK => "Macedonia",
136
+ :MO => "Macao",
137
+ :MK => "Macedonia, the Former Yugoslav Republic of",
143
138
  :MG => "Madagascar",
144
139
  :MW => "Malawi",
145
140
  :MY => "Malaysia",
@@ -151,11 +146,9 @@ module Sinatra
151
146
  :MR => "Mauritania",
152
147
  :MU => "Mauritius",
153
148
  :YT => "Mayotte",
154
- :FX => "Metropolitan France",
155
149
  :MX => "Mexico",
156
- :FM => "Micronesia",
157
- :MI => "Midway Islands",
158
- :MD => "Moldova",
150
+ :FM => "Micronesia, Federated States of",
151
+ :MD => "Moldova, Republic of",
159
152
  :MC => "Monaco",
160
153
  :MN => "Mongolia",
161
154
  :ME => "Montenegro",
@@ -168,7 +161,6 @@ module Sinatra
168
161
  :NP => "Nepal",
169
162
  :NL => "Netherlands",
170
163
  :AN => "Netherlands Antilles",
171
- :NT => "Neutral Zone",
172
164
  :NC => "New Caledonia",
173
165
  :NZ => "New Zealand",
174
166
  :NI => "Nicaragua",
@@ -176,21 +168,15 @@ module Sinatra
176
168
  :NG => "Nigeria",
177
169
  :NU => "Niue",
178
170
  :NF => "Norfolk Island",
179
- :KP => "North Korea",
180
- :VD => "North Vietnam",
181
171
  :MP => "Northern Mariana Islands",
182
172
  :NO => "Norway",
183
173
  :OM => "Oman",
184
- :QO => "Outlying Oceania",
185
- :PC => "Pacific Islands Trust Territory",
186
174
  :PK => "Pakistan",
187
175
  :PW => "Palau",
188
- :PS => "Palestinian Territory",
176
+ :PS => "Palestinian Territory, Occupied",
189
177
  :PA => "Panama",
190
- :PZ => "Panama Canal Zone",
191
178
  :PG => "Papua New Guinea",
192
179
  :PY => "Paraguay",
193
- :YD => "People's Democratic Republic of Yemen",
194
180
  :PE => "Peru",
195
181
  :PH => "Philippines",
196
182
  :PN => "Pitcairn",
@@ -198,12 +184,12 @@ module Sinatra
198
184
  :PT => "Portugal",
199
185
  :PR => "Puerto Rico",
200
186
  :QA => "Qatar",
201
- :RE => "Reunion",
187
+ :RE => "RÉunion",
202
188
  :RO => "Romania",
203
- :RU => "Russia",
189
+ :RU => "Russian Federation",
204
190
  :RW => "Rwanda",
205
- :BL => "Saint Barthélemy",
206
- :SH => "Saint Helena",
191
+ :BL => "Saint BarthÉlemy",
192
+ :SH => "Saint Helena, Ascension and Tristan Da Cunha",
207
193
  :KN => "Saint Kitts and Nevis",
208
194
  :LC => "Saint Lucia",
209
195
  :MF => "Saint Martin",
@@ -215,7 +201,6 @@ module Sinatra
215
201
  :SA => "Saudi Arabia",
216
202
  :SN => "Senegal",
217
203
  :RS => "Serbia",
218
- :CS => "Serbia and Montenegro",
219
204
  :SC => "Seychelles",
220
205
  :SL => "Sierra Leone",
221
206
  :SG => "Singapore",
@@ -225,7 +210,6 @@ module Sinatra
225
210
  :SO => "Somalia",
226
211
  :ZA => "South Africa",
227
212
  :GS => "South Georgia and the South Sandwich Islands",
228
- :KR => "South Korea",
229
213
  :ES => "Spain",
230
214
  :LK => "Sri Lanka",
231
215
  :SD => "Sudan",
@@ -234,11 +218,12 @@ module Sinatra
234
218
  :SZ => "Swaziland",
235
219
  :SE => "Sweden",
236
220
  :CH => "Switzerland",
237
- :SY => "Syria",
238
- :TW => "Taiwan",
221
+ :SY => "Syrian Arab Republic",
222
+ :TW => "Taiwan, Province of China",
239
223
  :TJ => "Tajikistan",
240
- :TZ => "Tanzania",
224
+ :TZ => "Tanzania, United Republic of",
241
225
  :TH => "Thailand",
226
+ :TL => "Timor-leste",
242
227
  :TG => "Togo",
243
228
  :TK => "Tokelau",
244
229
  :TO => "Tonga",
@@ -248,23 +233,20 @@ module Sinatra
248
233
  :TM => "Turkmenistan",
249
234
  :TC => "Turks and Caicos Islands",
250
235
  :TV => "Tuvalu",
251
- :PU => "U.S. Miscellaneous Pacific Islands",
252
- :VI => "U.S. Virgin Islands",
253
236
  :UG => "Uganda",
254
237
  :UA => "Ukraine",
255
- :SU => "Union of Soviet Socialist Republics",
256
238
  :AE => "United Arab Emirates",
257
239
  :GB => "United Kingdom",
258
240
  :US => "United States",
259
241
  :UM => "United States Minor Outlying Islands",
260
- :ZZ => "Unknown or Invalid Region",
261
242
  :UY => "Uruguay",
262
243
  :UZ => "Uzbekistan",
263
244
  :VU => "Vanuatu",
264
- :VA => "Vatican",
265
- :VE => "Venezuela",
266
- :VN => "Vietnam",
267
- :WK => "Wake Island",
245
+ :VA => "Vatican City State",
246
+ :VE => "Venezuela, Bolivarian Republic of",
247
+ :VN => "Viet Nam",
248
+ :VG => "Virgin Islands, British",
249
+ :VI => "Virgin Islands, U.S.",
268
250
  :WF => "Wallis and Futuna",
269
251
  :EH => "Western Sahara",
270
252
  :YE => "Yemen",
@@ -272,18 +254,50 @@ module Sinatra
272
254
  :ZW => "Zimbabwe"
273
255
  }
274
256
 
275
- def self.random_code
276
- @to_a ||= LOOKUP.to_a
277
- @to_a[rand(@to_a.size)].first
257
+ # @example
258
+ #
259
+ # p Country.to_select
260
+ # [["Afghanistan", "AF"], ["Åland Islands", "AX"], ["Albania", "AL"],
261
+ # ["Algeria", "DZ"], ["American Samoa", "AS"], ... ["Zimbabwe", "ZW"]]
262
+ #
263
+ # @return [Array] a collection of pairs with the first element being
264
+ # country name and the last element being the code.
265
+ #
266
+ # @see Sinatra::Helpers#country_choices
267
+ def to_select
268
+ all.map { |code, name| [name, code.to_s] }
278
269
  end
279
-
280
- def self.to_select
281
- LOOKUP.map { |code, name| [name, code] }
270
+
271
+ # Retrieves the country name given a country code.
272
+ # @example
273
+ #
274
+ # Sinatra::Helpers::Country["US"] == "United States"
275
+ # # => true
276
+ #
277
+ # Sinatra::Helpers::Country[:US] == "United States"
278
+ # # => true
279
+ #
280
+ # @param [#to_sym] code The country code in 2 letter all caps format.
281
+ # @return [String] The corresponding country name given the code.
282
+ # @return [nil] nil if no matching country code.
283
+ def [](code)
284
+ all[code.to_sym] if not code.to_s.empty?
282
285
  end
283
-
284
- def self.[](code)
285
- LOOKUP[code.to_sym] if not code.to_s.empty?
286
+
287
+ # For use with seeding dummy data.
288
+ # @return [Symbol] a randomized country code.
289
+ def random
290
+ all.keys.shuffle.first
286
291
  end
292
+
293
+ # Gives all countries in a Hash.
294
+ #
295
+ # @return [Hash] the code => name pairs of all countries.
296
+ def all
297
+ @all
298
+ end
299
+
300
+ module_function :all, :to_select, :[], :random
287
301
  end
288
302
  end
289
303
  end
@@ -1,7 +1,6 @@
1
1
  module Sinatra
2
2
  module Helpers
3
- # Taken from http://github.com/citrusbyte/reddit-clone
4
- # Credit goes to citrusbyte.
3
+ # @see http://github.com/citrusbyte/reddit-clone
5
4
  class HamlErrorPresenter < Ohm::Validations::Presenter
6
5
  def on(error, message = (block_given? ? @context.capture_haml { yield } : raise(ArgumentError)))
7
6
  handle(error) do
@@ -5,22 +5,22 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sinatra-helpers}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Cyril David"]
12
- s.date = %q{2010-05-06}
12
+ s.date = %q{2010-05-27}
13
13
  s.description = %q{Includes month_choices, year_choices, country_choices}
14
14
  s.email = %q{cyx.ucron@gmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.rdoc"
17
+ "README.markdown"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
21
  ".gitignore",
22
22
  "LICENSE",
23
- "README.rdoc",
23
+ "README.markdown",
24
24
  "Rakefile",
25
25
  "VERSION",
26
26
  "lib/sinatra/helpers.rb",
@@ -28,7 +28,9 @@ Gem::Specification.new do |s|
28
28
  "lib/sinatra/helpers/country.rb",
29
29
  "lib/sinatra/helpers/haml_error_presenter.rb",
30
30
  "sinatra-helpers.gemspec",
31
- "test/helper.rb"
31
+ "test/helper.rb",
32
+ "test/test_country.rb",
33
+ "test/test_sinatra_helpers.rb"
32
34
  ]
33
35
  s.homepage = %q{http://github.com/sinefunc/sinatra-helpers}
34
36
  s.rdoc_options = ["--charset=UTF-8"]
@@ -36,7 +38,9 @@ Gem::Specification.new do |s|
36
38
  s.rubygems_version = %q{1.3.6}
37
39
  s.summary = %q{Some generic helpers for the view layer}
38
40
  s.test_files = [
39
- "test/helper.rb"
41
+ "test/helper.rb",
42
+ "test/test_country.rb",
43
+ "test/test_sinatra_helpers.rb"
40
44
  ]
41
45
 
42
46
  if s.respond_to? :specification_version then
@@ -44,12 +48,30 @@ Gem::Specification.new do |s|
44
48
  s.specification_version = 3
45
49
 
46
50
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
+ s.add_runtime_dependency(%q<sinatra>, [">= 1.0"])
47
52
  s.add_development_dependency(%q<contest>, [">= 0"])
53
+ s.add_development_dependency(%q<mocha>, [">= 0"])
54
+ s.add_development_dependency(%q<rack-test>, [">= 0"])
55
+ s.add_development_dependency(%q<nokogiri>, [">= 0"])
56
+ s.add_development_dependency(%q<ohm>, [">= 0"])
57
+ s.add_development_dependency(%q<haml>, [">= 0"])
48
58
  else
59
+ s.add_dependency(%q<sinatra>, [">= 1.0"])
49
60
  s.add_dependency(%q<contest>, [">= 0"])
61
+ s.add_dependency(%q<mocha>, [">= 0"])
62
+ s.add_dependency(%q<rack-test>, [">= 0"])
63
+ s.add_dependency(%q<nokogiri>, [">= 0"])
64
+ s.add_dependency(%q<ohm>, [">= 0"])
65
+ s.add_dependency(%q<haml>, [">= 0"])
50
66
  end
51
67
  else
68
+ s.add_dependency(%q<sinatra>, [">= 1.0"])
52
69
  s.add_dependency(%q<contest>, [">= 0"])
70
+ s.add_dependency(%q<mocha>, [">= 0"])
71
+ s.add_dependency(%q<rack-test>, [">= 0"])
72
+ s.add_dependency(%q<nokogiri>, [">= 0"])
73
+ s.add_dependency(%q<ohm>, [">= 0"])
74
+ s.add_dependency(%q<haml>, [">= 0"])
53
75
  end
54
76
  end
55
77
 
@@ -1,10 +1,15 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'contest'
4
+ require 'mocha'
5
+ require 'rack/test'
6
+ require 'nokogiri'
7
+ require 'ohm'
8
+ require 'haml'
4
9
 
5
10
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
11
  $LOAD_PATH.unshift(File.dirname(__FILE__))
7
- require 'sinatra-helpers'
12
+ require 'sinatra/helpers'
8
13
 
9
14
  class Test::Unit::TestCase
10
15
  end
@@ -0,0 +1,29 @@
1
+ require "helper"
2
+
3
+ class CountryTest < Test::Unit::TestCase
4
+ include Sinatra::Helpers
5
+
6
+ test "241 countries" do
7
+ assert_equal 246, Country.to_select.length
8
+ end
9
+
10
+ test "has a matching name for all keys" do
11
+ Country.all.each do |code, name|
12
+ assert_equal name, Country[code]
13
+ assert_equal name, Country[code.to_s]
14
+ end
15
+ end
16
+
17
+ test "random returns a valid code" do
18
+ 246.times {
19
+ assert Country[Country.random]
20
+ }
21
+ end
22
+
23
+ test "finding a country with wrong parameters" do
24
+ assert_nil Country[""]
25
+ assert_nil Country[nil]
26
+ assert_nil Country[:XX]
27
+ assert_nil Country["XX"]
28
+ end
29
+ end
@@ -0,0 +1,298 @@
1
+ require "helper"
2
+
3
+ class SintatraHelpersTest < Test::Unit::TestCase
4
+ include Sinatra::Helpers
5
+
6
+ attr :settings
7
+
8
+ test "h" do
9
+ assert_equal "&lt;Foo&gt;", h("<Foo>")
10
+ assert_equal "&lt;Foo bar=&#39;baz&#39;&gt;", h("<Foo bar='baz'>")
11
+ assert_equal "&lt;Foo bar=&quot;baz&quot;&gt;", h("<Foo bar=\"baz\">")
12
+ end
13
+
14
+ test "country_choices returns Country.to_select" do
15
+ assert_equal Country.to_select, country_choices
16
+ end
17
+
18
+ test "day_choices returns 1 to 31" do
19
+ assert_equal 31, day_choices.size
20
+ assert_equal [1, 1], day_choices.first
21
+ assert_equal [31, 31], day_choices.last
22
+
23
+ day_choices.each do |label, value|
24
+ assert_equal label, value
25
+ end
26
+ end
27
+
28
+ describe "month choices" do
29
+ setup do
30
+ @settings = stub("Settings", :default_month_names => Date::MONTHNAMES)
31
+ end
32
+
33
+ test "by default" do
34
+ assert_equal ["January", 1], month_choices[0]
35
+ assert_equal ["February", 2], month_choices[1]
36
+ assert_equal ["March", 3], month_choices[2]
37
+ assert_equal ["April", 4], month_choices[3]
38
+ assert_equal ["May", 5], month_choices[4]
39
+ assert_equal ["June", 6], month_choices[5]
40
+ assert_equal ["July", 7], month_choices[6]
41
+ assert_equal ["August", 8], month_choices[7]
42
+ assert_equal ["September", 9], month_choices[8]
43
+ assert_equal ["October", 10], month_choices[9]
44
+ assert_equal ["November", 11], month_choices[10]
45
+ assert_equal ["December", 12], month_choices[11]
46
+ end
47
+
48
+ test "given Date::ABBR_MONTHNAMES" do
49
+ month_choices = month_choices(Date::ABBR_MONTHNAMES)
50
+
51
+ assert_equal ["Jan", 1], month_choices[0]
52
+ assert_equal ["Feb", 2], month_choices[1]
53
+ assert_equal ["Mar", 3], month_choices[2]
54
+ assert_equal ["Apr", 4], month_choices[3]
55
+ assert_equal ["May", 5], month_choices[4]
56
+ assert_equal ["Jun", 6], month_choices[5]
57
+ assert_equal ["Jul", 7], month_choices[6]
58
+ assert_equal ["Aug", 8], month_choices[7]
59
+ assert_equal ["Sep", 9], month_choices[8]
60
+ assert_equal ["Oct", 10], month_choices[9]
61
+ assert_equal ["Nov", 11], month_choices[10]
62
+ assert_equal ["Dec", 12], month_choices[11]
63
+ end
64
+
65
+ test "when changing settings.default_month_names" do
66
+ settings.expects(:default_month_names).at_least_once.returns(Date::ABBR_MONTHNAMES)
67
+
68
+ assert_equal ["Jan", 1], month_choices[0]
69
+ assert_equal ["Feb", 2], month_choices[1]
70
+ assert_equal ["Nov", 11], month_choices[10]
71
+ assert_equal ["Dec", 12], month_choices[11]
72
+ end
73
+ end
74
+
75
+ describe "year choices" do
76
+ setup do
77
+ @settings = stub("Settings", :default_year_loffset => -60,
78
+ :default_year_uoffset => 0)
79
+ end
80
+
81
+ test "by default" do
82
+ assert_equal 61, year_choices.size
83
+ year_choices.each do |label, value|
84
+ assert_equal label, value
85
+ end
86
+ end
87
+
88
+ test "allows to pass in a lower upper offset" do
89
+ assert_equal 1, year_choices(0, 0).size
90
+ assert_equal [Date.today.year, Date.today.year], year_choices(0, 0).first
91
+
92
+ Date.expects(:today).at_least_once.returns(Date.new(2010, 5, 5))
93
+ assert_equal [2005, 2005], year_choices(-5).first
94
+ assert_equal [2015, 2015], year_choices(0, 5).last
95
+ end
96
+
97
+ test "allows to customize via global settings" do
98
+ settings.expects(:default_year_loffset).at_least_once.returns(0)
99
+ settings.expects(:default_year_uoffset).at_least_once.returns(6)
100
+
101
+ expected = (2010..2016).to_a
102
+ expected = expected.zip(expected)
103
+
104
+ assert_equal expected, year_choices
105
+ end
106
+ end
107
+
108
+ context "in a real sinatra app" do
109
+ class App < Sinatra::Base
110
+ register Sinatra::Helpers
111
+
112
+ get '/years' do
113
+ year_choices.to_s
114
+ end
115
+
116
+ get '/months' do
117
+ month_choices.to_s
118
+ end
119
+ end
120
+
121
+ include Rack::Test::Methods
122
+
123
+ def app
124
+ App.new
125
+ end
126
+
127
+ test "returns the expected years" do
128
+ get '/years'
129
+
130
+ settings.stubs(:default_year_loffset).returns(-60)
131
+ settings.stubs(:default_year_uoffset).returns(0)
132
+
133
+ assert_equal year_choices.to_s, last_response.body
134
+ end
135
+
136
+ test "returns the expected months" do
137
+ get '/months'
138
+
139
+ settings.stubs(:default_month_names).returns(Date::MONTHNAMES)
140
+ assert_equal month_choices.to_s, last_response.body
141
+ end
142
+ end
143
+
144
+ describe "select_options" do
145
+ test "displays the pairs" do
146
+ html = select_options([['One', 1], ['Two', 2]])
147
+ doc = Nokogiri(%(<body>#{html}</body>))
148
+
149
+ assert_equal 'One', doc.search('option[value="1"]').text
150
+ assert_equal 'Two', doc.search('option[value="2"]').text
151
+ end
152
+
153
+ test "marks option as selected" do
154
+ html = select_options([['One', 1], ['Two', 2]], 1)
155
+ doc = Nokogiri(%(<body>#{html}</body>))
156
+
157
+ assert_equal 'One', doc.search('option[value="1"][selected]').text
158
+ assert_equal 'Two', doc.search('option[value="2"]').text
159
+ end
160
+
161
+ test "produces a prompt properly" do
162
+ html = select_options([['One', 1], ['Two', 2]], 1, "- Choose -")
163
+ doc = Nokogiri(%(<body>#{html}</body>))
164
+
165
+ assert_equal '- Choose -', doc.search('option[value=""]').text
166
+ assert_equal 'One', doc.search('option[value="1"][selected]').text
167
+ assert_equal 'Two', doc.search('option[value="2"]').text
168
+ end
169
+ end
170
+
171
+ describe "tag" do
172
+ test "the basic no attr case" do
173
+ assert_equal '<div>Foobar</div>', tag('div', 'Foobar')
174
+ end
175
+
176
+ test "one attr case" do
177
+ assert_equal '<div class="baz">Foobar</div>',
178
+ tag('div', 'Foobar', :class => 'baz')
179
+ end
180
+
181
+ test "many attrs case" do
182
+ assert_equal '<div class="baz bar" style="display:none">Foobar</div>',
183
+ tag('div', 'Foobar', :class => 'baz bar', :style => 'display:none')
184
+ end
185
+
186
+ test "funky attrs case" do
187
+ assert_equal '<div class="baz &#39;bar&#39;" ' +
188
+ 'style="display:&quot;none&quot;">Foobar</div>',
189
+ tag('div', 'Foobar', :class => "baz 'bar'", :style => 'display:"none"')
190
+ end
191
+ end
192
+
193
+ describe "errors_on" do
194
+ include Rack::Test::Methods
195
+
196
+ class App < Sinatra::Base
197
+ FORM = (<<-FORM).gsub(/^ {6}/, '')
198
+ - errors_on @post do |e|
199
+ - e.on [:email, :not_present], "Email is required."
200
+ - e.on [:name, :not_present], "Name is required."
201
+ FORM
202
+
203
+ register Sinatra::Helpers
204
+
205
+ class Post < Ohm::Model
206
+ attribute :email
207
+ attribute :name
208
+
209
+ def validate
210
+ assert_present :email
211
+ assert_present :name
212
+ end
213
+ end
214
+
215
+ get '/form' do
216
+ @post = Post.new
217
+ @post.valid?
218
+
219
+ haml FORM
220
+ end
221
+ end
222
+
223
+ def app
224
+ App.new
225
+ end
226
+
227
+ test "produces proper errors" do
228
+ get '/form'
229
+
230
+ doc = Nokogiri(last_response.body)
231
+
232
+ assert_equal 1, doc.search('div.errors').length
233
+
234
+ assert_equal 'Email is required.',
235
+ doc.search('div.errors > ul > li:first-child').text
236
+
237
+ assert_equal 'Name is required.',
238
+ doc.search('div.errors > ul > li:last-child').text
239
+ end
240
+ end
241
+
242
+ describe "currency" do
243
+ setup do
244
+ settings.stubs(:default_currency_unit).returns('$')
245
+ settings.stubs(:default_currency_precision).returns(2)
246
+ settings.stubs(:default_currency_separator).returns(',')
247
+ end
248
+
249
+ test "nil" do
250
+ assert_nil currency(nil)
251
+ end
252
+
253
+ test "defaults" do
254
+ assert_equal "$ 10.00", currency(10)
255
+ end
256
+
257
+ test "with custom unit, precision" do
258
+ assert_equal "&pound; 10.0", currency(10, :unit => "&pound;", :precision => 1)
259
+ end
260
+
261
+ test "with 0 precision" do
262
+ assert_equal "$ 10", currency(10, :precision => 0)
263
+ end
264
+
265
+ test "separators" do
266
+ assert_equal "$ 100.00", currency(100)
267
+ assert_equal "$ 1,000.00", currency(1_000)
268
+ assert_equal "$ 10,000.00", currency(10_000)
269
+ assert_equal "$ 100,000.00", currency(100_000)
270
+ assert_equal "$ 1,000,000.00", currency(1_000_000)
271
+ end
272
+
273
+ test "specified defaults" do
274
+ settings.stubs(:default_currency_unit).returns('P')
275
+ settings.stubs(:default_currency_precision).returns(3)
276
+ settings.stubs(:default_currency_separator).returns(' ')
277
+
278
+ assert_equal "P 100.000", currency(100)
279
+ assert_equal "P 1 000.000", currency(1_000)
280
+ assert_equal "P 10 000.000", currency(10_000)
281
+ end
282
+ end
283
+
284
+ describe "percentage" do
285
+ test "nil" do
286
+ assert_nil percentage(nil)
287
+ end
288
+
289
+ test "various percentages" do
290
+ assert_equal '0.01%', percentage(0.01)
291
+ assert_equal '0.10%', percentage(0.10)
292
+ assert_equal '1%', percentage(1.00)
293
+ assert_equal '10.01%', percentage(10.01)
294
+ assert_equal '99.99%', percentage(99.99)
295
+ assert_equal '100%', percentage(100)
296
+ end
297
+ end
298
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 1
9
- version: 0.1.1
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Cyril David
@@ -14,13 +14,26 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-06 00:00:00 +08:00
17
+ date: 2010-05-27 00:00:00 +08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: contest
21
+ name: sinatra
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 0
30
+ version: "1.0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: contest
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
24
37
  requirements:
25
38
  - - ">="
26
39
  - !ruby/object:Gem::Version
@@ -28,7 +41,67 @@ dependencies:
28
41
  - 0
29
42
  version: "0"
30
43
  type: :development
31
- version_requirements: *id001
44
+ version_requirements: *id002
45
+ - !ruby/object:Gem::Dependency
46
+ name: mocha
47
+ prerelease: false
48
+ requirement: &id003 !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ type: :development
56
+ version_requirements: *id003
57
+ - !ruby/object:Gem::Dependency
58
+ name: rack-test
59
+ prerelease: false
60
+ requirement: &id004 !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ type: :development
68
+ version_requirements: *id004
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ prerelease: false
72
+ requirement: &id005 !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id005
81
+ - !ruby/object:Gem::Dependency
82
+ name: ohm
83
+ prerelease: false
84
+ requirement: &id006 !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id006
93
+ - !ruby/object:Gem::Dependency
94
+ name: haml
95
+ prerelease: false
96
+ requirement: &id007 !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ type: :development
104
+ version_requirements: *id007
32
105
  description: Includes month_choices, year_choices, country_choices
33
106
  email: cyx.ucron@gmail.com
34
107
  executables: []
@@ -37,12 +110,12 @@ extensions: []
37
110
 
38
111
  extra_rdoc_files:
39
112
  - LICENSE
40
- - README.rdoc
113
+ - README.markdown
41
114
  files:
42
115
  - .document
43
116
  - .gitignore
44
117
  - LICENSE
45
- - README.rdoc
118
+ - README.markdown
46
119
  - Rakefile
47
120
  - VERSION
48
121
  - lib/sinatra/helpers.rb
@@ -51,6 +124,8 @@ files:
51
124
  - lib/sinatra/helpers/haml_error_presenter.rb
52
125
  - sinatra-helpers.gemspec
53
126
  - test/helper.rb
127
+ - test/test_country.rb
128
+ - test/test_sinatra_helpers.rb
54
129
  has_rdoc: true
55
130
  homepage: http://github.com/sinefunc/sinatra-helpers
56
131
  licenses: []
@@ -83,3 +158,5 @@ specification_version: 3
83
158
  summary: Some generic helpers for the view layer
84
159
  test_files:
85
160
  - test/helper.rb
161
+ - test/test_country.rb
162
+ - test/test_sinatra_helpers.rb
@@ -1,38 +0,0 @@
1
- = sinatra-helpers
2
-
3
- Bare minimum, close to the metal helpers for your average sinatra application.
4
-
5
- == Examples
6
-
7
- %select(name='card[month'])
8
- != month_choices
9
-
10
- %select(name='card[year'])
11
- != year_choices
12
-
13
- %select(name='address[country]')
14
- != country_choices
15
-
16
- # If you have an ohm model which you want to present the errors of:
17
- # (this is taken from the reddit-clone courtesy of citrusbyte)
18
-
19
- # This should be put in your HAML file
20
-
21
- - errors_on @user do |e|
22
- - e.on [:email, :not_present] "You must supply an email address"
23
- - e.on [:password, :not_present] "A password is required"
24
- - e.on [:password, :not_confirmed] "You must confirm your password"
25
-
26
- == Note on Patches/Pull Requests
27
-
28
- * Fork the project.
29
- * Make your feature addition or bug fix.
30
- * Add tests for it. This is important so I don't break it in a
31
- future version unintentionally.
32
- * Commit, do not mess with rakefile, version, or history.
33
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
34
- * Send me a pull request. Bonus points for topic branches.
35
-
36
- == Copyright
37
-
38
- Copyright (c) 2010 Cyril David. See LICENSE for details.