sinatra-helpers 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/README.markdown +58 -0
- data/Rakefile +6 -0
- data/VERSION +1 -1
- data/lib/sinatra/helpers.rb +210 -13
- data/lib/sinatra/helpers/compat-1.8.6.rb +5 -2
- data/lib/sinatra/helpers/country.rb +78 -64
- data/lib/sinatra/helpers/haml_error_presenter.rb +1 -2
- data/sinatra-helpers.gemspec +28 -6
- data/test/helper.rb +6 -1
- data/test/test_country.rb +29 -0
- data/test/test_sinatra_helpers.rb +298 -0
- metadata +85 -8
- data/README.rdoc +0 -38
data/.gitignore
CHANGED
data/README.markdown
ADDED
@@ -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
|
+
0.2.0
|
data/lib/sinatra/helpers.rb
CHANGED
@@ -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
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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 => "£") == "£ 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, '£'
|
198
|
+
# set :default_currency_precision, 3
|
199
|
+
# set :default_currency_separator, ' '
|
200
|
+
#
|
201
|
+
# currency(100) == "£ 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(
|
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
|
-
|
251
|
+
def escape_attr(str)
|
252
|
+
str.to_s.gsub("'", "'").gsub('"', """)
|
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
|
-
|
6
|
-
|
5
|
+
# A simple module containing all countries as of 2010.
|
6
|
+
module Country
|
7
|
+
@all = {
|
7
8
|
:AF => "Afghanistan",
|
8
|
-
:AX => "
|
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
|
-
:
|
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
|
60
|
-
:CD => "Congo
|
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
|
-
:
|
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-
|
99
|
+
:GW => "Guinea-bissau",
|
106
100
|
:GY => "Guyana",
|
107
101
|
:HT => "Haiti",
|
108
|
-
:HM => "Heard Island and
|
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 => "
|
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 => "
|
132
|
+
:LY => "Libyan Arab Jamahiriya",
|
138
133
|
:LI => "Liechtenstein",
|
139
134
|
:LT => "Lithuania",
|
140
135
|
:LU => "Luxembourg",
|
141
|
-
:MO => "
|
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
|
-
:
|
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 => "
|
187
|
+
:RE => "RÉunion",
|
202
188
|
:RO => "Romania",
|
203
|
-
:RU => "
|
189
|
+
:RU => "Russian Federation",
|
204
190
|
:RW => "Rwanda",
|
205
|
-
:BL => "Saint
|
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 => "
|
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 => "
|
267
|
-
:
|
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
|
-
|
276
|
-
|
277
|
-
|
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
|
-
|
281
|
-
|
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
|
-
|
285
|
-
|
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
|
-
#
|
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
|
data/sinatra-helpers.gemspec
CHANGED
@@ -5,22 +5,22 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sinatra-helpers}
|
8
|
-
s.version = "0.
|
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-
|
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.
|
17
|
+
"README.markdown"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".gitignore",
|
22
22
|
"LICENSE",
|
23
|
-
"README.
|
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
|
|
data/test/helper.rb
CHANGED
@@ -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
|
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 "<Foo>", h("<Foo>")
|
10
|
+
assert_equal "<Foo bar='baz'>", h("<Foo bar='baz'>")
|
11
|
+
assert_equal "<Foo bar="baz">", 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 'bar'" ' +
|
188
|
+
'style="display:"none"">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 "£ 10.0", currency(10, :unit => "£", :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
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
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-
|
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:
|
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: *
|
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.
|
113
|
+
- README.markdown
|
41
114
|
files:
|
42
115
|
- .document
|
43
116
|
- .gitignore
|
44
117
|
- LICENSE
|
45
|
-
- README.
|
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
|
data/README.rdoc
DELETED
@@ -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.
|