web-utils 0.1.4 → 0.1.5

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/web_utils.rb +153 -69
  3. data/test/test_web_utils.rb +22 -6
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c51f28f3490e185eefa169866d88af1b0cf15ce3a61f7a8fbdb9acf955dd160a
4
- data.tar.gz: b047825464803b6a4c49f79dae32d8159b38f5e3edef97c9712f647bf258a920
3
+ metadata.gz: 74c9972b2a2cfeb97d05475c3833378dfe7b83350e5764e281888c3f7e206b67
4
+ data.tar.gz: 82f8929a62f9b94e130514f9191f0be756b7f7ef49ab1e6e5105113d53068ce4
5
5
  SHA512:
6
- metadata.gz: f3cecb91f83b58fe4c03fceb8941afe56c4dd43d0996adb4a0a92d90cbd413309c4af23c047ba199647a00f14640993becb5765903d07378e78922797d6c5b44
7
- data.tar.gz: 9227bf1102a6747c5375386ceba11982b929025b83078850e15817d3876d4f1f5817dff32c401ddf2320de40febcf6abe3c89e843912cbf9452955c5b1f1420c
6
+ metadata.gz: 4488aa8e08eddc957a2626662bc3eda75b59c049435e9f4b37eb2cbd6574335d178373c0cf97e289797b9451966838017753f2c2e15e21f4fe751cb4bde55def
7
+ data.tar.gz: 144b9995c41472af73386bfe7ffa1a4e0f4df5f5dca6d929dbd10a0118c42a265b0d99ef753f2916935535e182580038b1c51fcf85c679c84a69ffa17f2f4ed1
@@ -5,59 +5,104 @@ require 'uri'
5
5
 
6
6
  module WebUtils
7
7
 
8
- VERSION = '0.1.4'
8
+ VERSION = '0.1.5'.freeze
9
9
 
10
10
  # Most methods are supposed to be as simple as possible
11
11
  # and just cover most cases.
12
- # I would rather override specific cases rather than making
12
+ # I would rather override specific cases than making
13
13
  # complicated methods.
14
14
 
15
15
  extend Rack::Utils
16
16
 
17
+ # Global string constants
18
+ EMPTY_STRING = ''.freeze
19
+ IES_STRING = 'ies'.freeze
20
+ E_STRING = 'e'.freeze
21
+ S_STRING = 's'.freeze
22
+ Y_STRING = 'y'.freeze
23
+ X_STRING = 'x'.freeze
24
+ XES_STRING = 'xes'.freeze
25
+ SPACE = ' '.freeze
26
+ DASH = '-'.freeze
27
+ UNDERSCORE = '_'.freeze
28
+ AMPERSAND = '&'.freeze
29
+ PERCENT = '%'.freeze
30
+ PIPE = '|'
31
+ DOT = '.'.freeze
32
+ COMMA = ','.freeze
33
+ CONST_SEP = '::'.freeze
34
+ ELLIPSIS = '...'
35
+ AND_STRING = 'and'.freeze
36
+ SPACE_PERCENT_STRING = ' percent'.freeze
37
+ TRUE_STRING = 'true'.freeze
38
+ FALSE_STRING = 'false'.freeze
39
+ BR_TAG = '<br>'.freeze
40
+ ARG1_SUB = '\1'.freeze
41
+
42
+ # From then on, constants preceed the methods they are
43
+ # used on.
44
+
45
+ BLANK_RE = /\A[[:space:]]*\z/.freeze
46
+
17
47
  def blank? s
18
- s.to_s.strip==''
48
+ return true if s.nil?
49
+ # Not much difference with strip on benchmarks
50
+ # return (s.empty? or BLANK_RE.match?(s)) if s.is_a?(String)
51
+ return (s.strip.empty?) if s.is_a?(String)
52
+ return s.empty? if s.respond_to?(:empty?)
53
+ return true if s==false
54
+ false
19
55
  end
20
56
  module_function :blank?
21
57
 
58
+ PLURAL_RE = /([b-df-hj-np-tv-z])ys\z/.freeze
59
+ PLURAL_SUB = '\1ies'.freeze
60
+
22
61
  def pluralize s
23
- s<<'e' if s[-1,1]=='x'
24
- s<<'s'
25
- s.sub(/([b-df-hj-np-tv-z])ys$/,'\1ies')
62
+ s = s.dup
63
+ s<<E_STRING if s[-1,1]==X_STRING
64
+ s<<S_STRING
65
+ s.sub PLURAL_RE, PLURAL_SUB
26
66
  end
27
67
  module_function :pluralize
28
68
 
69
+ SINGULAR_RE = /ies\z/.freeze
70
+
29
71
  def singularize s
30
- case s
31
- when /xes$/
72
+ if s.end_with? XES_STRING
32
73
  s[0..-3]
33
- when /ies$/
34
- s.sub(/ies$/, 'y')
35
- when /s$/
74
+ elsif s.end_with? IES_STRING
75
+ s.sub(SINGULAR_RE, Y_STRING)
76
+ elsif s.end_with? S_STRING
36
77
  s[0..-2]
37
78
  else
38
- s
79
+ s.dup
39
80
  end
40
81
  end
41
82
  module_function :singularize
42
83
 
84
+ UPPER_OR_NUM_RE = /([A-Z]|\d+)/.freeze
85
+
43
86
  def dasherize_class_name s
44
- s.gsub(/([A-Z]|\d+)/){|str|"-#{str.downcase}"}[1..-1].gsub('::','-')
87
+ s.gsub(UPPER_OR_NUM_RE) {|str| "-#{str.downcase}" }[1..-1].gsub(CONST_SEP, DASH)
45
88
  end
46
89
  module_function :dasherize_class_name
47
90
 
91
+ DASH_LOWER_OR_NUM_RE = /\-([a-z0-9])/.freeze
92
+
48
93
  def undasherize_class_name s
49
- s.capitalize.gsub(/\-([a-z0-9])/){|str|$1.upcase}.gsub('-','::')
94
+ s.capitalize.gsub(DASH_LOWER_OR_NUM_RE) {|str| $1.upcase }.gsub(DASH, CONST_SEP)
50
95
  end
51
96
  module_function :undasherize_class_name
52
97
 
53
98
  def resolve_class_name s, context=Kernel
54
- current, *payload = s.to_s.split('::')
99
+ current, *payload = s.to_s.split(CONST_SEP)
55
100
  raise(NameError) if current.nil?
56
101
  const = context.const_get(current)
57
102
  if payload.empty?
58
103
  const
59
104
  else
60
- resolve_class_name(payload.join('::'),const)
105
+ resolve_class_name(payload.join(CONST_SEP),const)
61
106
  end
62
107
  end
63
108
  module_function :resolve_class_name
@@ -67,12 +112,15 @@ module WebUtils
67
112
  end
68
113
  module_function :resolve_dasherized_class_name
69
114
 
115
+ START_UPPER_RE = /^[A-Z]/.freeze
116
+ START_LOWER_RE = /^[a-z]/.freeze
117
+
70
118
  def guess_related_class_name context, clue
71
119
  context.respond_to?(:name) ? context.name : context.to_s
72
120
  clue = clue.to_s
73
- return clue if clue=~/^[A-Z]/
74
- if clue=~/^[a-z]/
75
- clue = undasherize_class_name singularize(clue).gsub('_','-')
121
+ return clue if clue =~ START_UPPER_RE
122
+ if clue =~ START_LOWER_RE
123
+ clue = undasherize_class_name singularize(clue).gsub(UNDERSCORE, DASH)
76
124
  clue = "::#{clue}"
77
125
  end
78
126
  "#{context}#{clue}"
@@ -96,39 +144,43 @@ module WebUtils
96
144
  module_function :deep_copy
97
145
 
98
146
  def ensure_key! h, k, v
99
- h[k] = v unless h.key?(k)
100
- h[k]
147
+ h.fetch(k) {|k| h.store(k, v) }
101
148
  end
102
149
  module_function :ensure_key!
103
150
 
104
151
  def ensure_key h, k, v
105
- new_h = h.dup
106
- self.ensure_key! new_h, k, v
107
- new_h
152
+ {k=>v}.merge h
108
153
  end
109
154
  module_function :ensure_key
110
155
 
111
- ACCENTS = "ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž"
112
- WITHOUT_ACCENTS = "AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz"
156
+ ACCENTS = "ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž".freeze
157
+ WITHOUT_ACCENTS = "AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz".freeze
158
+ DASHIFY_RE = /(\-|[^0-9a-zA-Z])+/.freeze
159
+ EDGE_DASH_RE = /(\A-|-\z)/.freeze
160
+
113
161
  def slugify s, force_lower=true
114
162
  s = s.to_s
115
163
  .tr(ACCENTS, WITHOUT_ACCENTS)
116
- .gsub(/&/, 'and')
117
- .gsub(/%/, ' percent')
118
- .gsub(/(\-|[^0-9a-zA-Z])+/,'-')
119
- .gsub(/(^-|-$)/,'')
164
+ .gsub(AMPERSAND, AND_STRING)
165
+ .gsub(PERCENT, SPACE_PERCENT_STRING)
166
+ .gsub(DASHIFY_RE, DASH)
167
+ .gsub(EDGE_DASH_RE, EMPTY_STRING)
120
168
  s = s.downcase if force_lower
121
169
  escape(s)
122
170
  end
123
171
  module_function :slugify
124
172
 
173
+ ALPHA_NUM_RE = /[a-zA-Z0-9]+/.freeze
174
+
125
175
  def label_for_field field_name
126
- field_name.to_s.scan(/[a-zA-Z0-9]+/).map(&:capitalize).join(' ')
176
+ field_name.to_s.scan(ALPHA_NUM_RE).map(&:capitalize).join(SPACE)
127
177
  end
128
178
  module_function :label_for_field
129
179
 
180
+ EACH_STUB_ERR_MSG = 'WebUtils.each_stub expects an object which respond to each_with_index.'
181
+
130
182
  def each_stub obj, &block
131
- raise TypeError, 'WebUtils.each_stub expects an object which respond to each_with_index' unless obj.respond_to?(:each_with_index)
183
+ raise TypeError, EACH_STUB_ERR_MSG unless obj.respond_to?(:each_with_index)
132
184
  obj.each_with_index do |(k,v),i|
133
185
  value = v || k
134
186
  if value.is_a?(Hash) || value.is_a?(Array)
@@ -140,7 +192,10 @@ module WebUtils
140
192
  end
141
193
  module_function :each_stub
142
194
 
143
- TYPECASTABLE = [:bool, :boolean, :nil, :int, :integer, :float]
195
+ TYPECASTABLE = [:bool, :boolean, :nil, :int, :integer, :float].freeze
196
+ INT_RE = /\A-?\d+\z/.freeze
197
+ FLOAT_RE = /\A-?\d*\.\d+\z/.freeze
198
+
144
199
  def automatic_typecast str, casted=TYPECASTABLE
145
200
  return str unless str.is_a?(String)
146
201
  casted = casted.map do |sym|
@@ -153,15 +208,15 @@ module WebUtils
153
208
  sym
154
209
  end
155
210
  end
156
- if casted.include?(:boolean) and str=='true'
211
+ if casted.include?(:boolean) and str == TRUE_STRING
157
212
  true
158
- elsif casted.include?(:boolean) and str=='false'
213
+ elsif casted.include?(:boolean) and str == FALSE_STRING
159
214
  false
160
- elsif casted.include?(:nil) and str==''
215
+ elsif casted.include?(:nil) and str == EMPTY_STRING
161
216
  nil
162
- elsif casted.include?(:integer) and str=~/^-?\d+$/
217
+ elsif casted.include?(:integer) and str =~ INT_RE
163
218
  str.to_i
164
- elsif casted.include?(:float) and str=~/^-?\d*\.\d+$/
219
+ elsif casted.include?(:float) and str =~ FLOAT_RE
165
220
  str.to_f
166
221
  else
167
222
  str
@@ -169,23 +224,29 @@ module WebUtils
169
224
  end
170
225
  module_function :automatic_typecast
171
226
 
172
- ID_CHARS = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
227
+ ID_CHARS = (('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a).freeze.map(&:freeze)
173
228
  ID_SIZE = 16
229
+ DEPRECATED_RANDOM_ID_STRING = 'WebUtils::generate_random_id is deprecated. Use standard SecureRandom instead.'.freeze
230
+
174
231
  def generate_random_id size=ID_SIZE
175
- warn "WebUtils::generate_random_id is deprecated. Use standard SecureRandom instead."
176
- id = ''
232
+ warn DEPRECATED_RANDOM_ID_STRING
233
+ id = String.new
177
234
  size.times{id << ID_CHARS[rand(ID_CHARS.size)]}
178
235
  id
179
236
  end
180
237
  module_function :generate_random_id
181
238
 
182
- def nl2br s, br='<br>'
183
- s.to_s.gsub(/\r?\n/,br)
239
+ RN_RE = /\r?\n/.freeze
240
+
241
+ def nl2br s, br=BR_TAG
242
+ s.to_s.gsub(RN_RE, br)
184
243
  end
185
244
  module_function :nl2br
186
245
 
246
+ COMPLETE_LINK_RE = /^(\/|[a-z]*:)/.freeze
247
+
187
248
  def complete_link link
188
- if blank?(link) or link=~/^(\/|[a-z]*:)/
249
+ if blank?(link) or link =~ COMPLETE_LINK_RE
189
250
  link
190
251
  else
191
252
  "//#{link}"
@@ -193,14 +254,17 @@ module WebUtils
193
254
  end
194
255
  module_function :complete_link
195
256
 
257
+ EXTERNAL_LINK_RE = /\A[a-z]*:?\/\//.freeze
258
+
196
259
  def external_link? link
197
- !!(link =~ /^[a-z]*:?\/\//)
260
+ !!(link =~ EXTERNAL_LINK_RE)
198
261
  end
199
262
  module_function :external_link?
200
263
 
201
- EMAIL_REGEX = /([^\s]+@[^\s]*[a-zA-Z])/
202
- LINK_REGEX = /\b((https?:\/\/|ftps?:\/\/|www\.)([A-Za-z0-9\-_=%&@\?\.\/]+))\b/
203
- def automatic_html s, br='<br>'
264
+ EMAIL_REGEX = /([^\s]+@[^\s]*[a-zA-Z])/.freeze
265
+ LINK_REGEX = /\b((https?:\/\/|ftps?:\/\/|www\.)([A-Za-z0-9\-_=%&@\?\.\/]+))\b/.freeze
266
+
267
+ def automatic_html s, br=BR_TAG
204
268
  replaced = s.to_s.
205
269
  gsub(LINK_REGEX) do |str|
206
270
  url = complete_link $1
@@ -213,51 +277,69 @@ module WebUtils
213
277
  end
214
278
  module_function :automatic_html
215
279
 
216
- TAG_REGEX = /<[^>]*>/
217
- def truncate s,c=320,ellipsis='...'
280
+ TAG_REGEX = /<[^>]*>/.freeze
281
+ NL_RE = /\n/.freeze
282
+
283
+ def truncate s, c=320, ellipsis=ELLIPSIS
218
284
  s.to_s
219
- .gsub(TAG_REGEX, '')
220
- .gsub(/\n/, ' ')
221
- .sub(/^(.{#{c}}\w*).*$/m, '\1'+ellipsis)
285
+ .gsub(TAG_REGEX, EMPTY_STRING)
286
+ .gsub(NL_RE, SPACE)
287
+ .sub(/^(.{#{c}}\w*).*$/m, ARG1_SUB+ellipsis)
222
288
  end
223
289
  module_function :truncate
224
290
 
291
+ QUERY_SPLITTER = /[^a-zA-Z0-9\&]+/.freeze
292
+
225
293
  def regex_for_query query, exhaustive=true
226
- atoms = query.split(/[^a-zA-Z0-9\&]+/)
294
+ atoms = query.split(QUERY_SPLITTER)
227
295
  atom_patterns = atoms.map{|a| "(?=.*\\b#{a})" }
228
- sep = exhaustive ? '' : '|'
229
- regex = /#{atom_patterns.join(sep)}/i
296
+ sep = exhaustive ? EMPTY_STRING : PIPE
297
+ /#{atom_patterns.join(sep)}/i.freeze
230
298
  end
231
299
  module_function :regex_for_query
232
300
 
301
+ PRICE_ERR_MSG = 'The price needs to be the price in cents/pence as an integer'.freeze
302
+ PRICE_FMT = '%.2f'.freeze
303
+ NO_CENTS_RE = /\.00/.freeze
304
+ THOUSANDS_RE = /(\d{3})(?=\d)/.freeze
305
+ THOUSANDS_SUB = '\1,'.freeze
306
+
233
307
  def display_price int
234
308
  unless int.is_a?(Integer)
235
- raise(TypeError, 'The price needs to be the price in cents/pence as an integer')
309
+ raise(TypeError, PRICE_ERR_MSG)
236
310
  end
237
- ("%.2f" % (int/100.0))
238
- .sub(/\.00/, '')
311
+ (PRICE_FMT % (int/100.0))
312
+ .sub(NO_CENTS_RE, EMPTY_STRING)
239
313
  .reverse
240
- .gsub(/(\d{3})(?=\d)/, '\\1,')
314
+ .gsub(THOUSANDS_RE, THOUSANDS_SUB)
241
315
  .reverse
242
316
  end
243
317
  module_function :display_price
244
318
 
319
+ PRICE_PARSE_ERR_MSG = 'The price needs to be parsed from a String'.freeze
320
+ SWITCH_DOT_COMMA_TR = ['.,'.freeze, ',.'.freeze].freeze
321
+ COMMA_BASED_PRICE_RE = /(\.\d\d\d|,\d\d?)\z/.freeze
322
+ NON_PRICE_CHARS_RE = /[^\d\.\-,]/.freeze
323
+
245
324
  def parse_price string
246
325
  unless string.is_a?(String)
247
- raise(TypeError, 'The price needs to be parsed from a String')
326
+ raise(TypeError, PRICE_PARSE_ERR_MSG)
248
327
  end
249
- string = string.gsub(/[^\d\.\-,]/, '')
250
- if string[/\.\d\d\d$/] or string[/,\d\d?$/]
328
+ string = string.gsub(NON_PRICE_CHARS_RE, EMPTY_STRING)
329
+ if string[COMMA_BASED_PRICE_RE]
251
330
  # comma-based price
252
- string = string.tr '.,', ',.'
331
+ string = string.tr(*SWITCH_DOT_COMMA_TR)
253
332
  end
254
- ("%.2f" % string.gsub(/,/, '')).gsub(/\./,'').to_i
333
+ (PRICE_FMT % string.gsub(COMMA, EMPTY_STRING)).gsub(DOT, EMPTY_STRING).to_i
255
334
  end
256
335
  module_function :parse_price
257
336
 
258
- def branded_filename path, brand='WebUtils'
337
+ DEFAULT_BRAND = self.name
338
+ START_DOT_SLASH_RE = /\A\.\//.freeze
339
+
340
+ def branded_filename path, brand=DEFAULT_BRAND
259
341
  "#{File.dirname(path)}/#{brand}-#{File.basename(path)}"
260
- .sub(/^\.\//,'')
342
+ .sub(START_DOT_SLASH_RE, EMPTY_STRING)
261
343
  end
262
344
  module_function :branded_filename
263
345
 
@@ -268,12 +350,14 @@ module WebUtils
268
350
  module_function :filename_variation
269
351
 
270
352
  def initial_request? request
271
- return true unless request.referer=~URI.regexp
272
353
  URI.parse(request.referer).host!=request.host
354
+ rescue URI::InvalidURIError
355
+ return true
273
356
  end
274
357
  module_function :initial_request?
275
358
 
276
- BOT_REGEX = /bot|crawl|slurp|spider/i
359
+ BOT_REGEX = /bot|crawl|slurp|spider/i.freeze
360
+
277
361
  def being_crawled? request
278
362
  request.user_agent =~ BOT_REGEX
279
363
  end
@@ -26,6 +26,9 @@ describe WebUtils do
26
26
  describe 'with nil' do
27
27
  it('is true') { assert utils.blank?(nil) }
28
28
  end
29
+ describe 'with false' do
30
+ it('is true') { assert utils.blank?(false) }
31
+ end
29
32
  describe 'with non-blank strings' do
30
33
  it 'is false' do
31
34
  ['a','abc', ' abc '].each do |s|
@@ -54,6 +57,11 @@ describe WebUtils do
54
57
  assert_equal 'copies', utils.pluralize('copy')
55
58
  end
56
59
  end
60
+ it "Does not mutate input" do
61
+ input = 'bag'
62
+ utils.pluralize(input)
63
+ assert_equal 'bag', input
64
+ end
57
65
 
58
66
  end
59
67
 
@@ -72,6 +80,14 @@ describe WebUtils do
72
80
  assert_equal 'copy', utils.singularize('copies')
73
81
  end
74
82
  end
83
+ describe "The word does not seem plural" do
84
+ it "Returns the same" do
85
+ input = 'bag'
86
+ output = utils.singularize(input)
87
+ assert_equal 'bag', output
88
+ refute_same input, output
89
+ end
90
+ end
75
91
 
76
92
  end
77
93
 
@@ -350,14 +366,14 @@ describe WebUtils do
350
366
 
351
367
  describe '#generate_random_id' do
352
368
  it 'Has the correct format' do
353
- out, err = capture_io do
354
- assert_match /[a-zA-Z0-9]{16}/, utils.generate_random_id
369
+ _, err = capture_io do
370
+ assert_match(/[a-zA-Z0-9]{16}/, utils.generate_random_id )
355
371
  end
356
372
  assert_match "WebUtils::generate_random_id is deprecated", err
357
373
  end
358
374
  it 'Can have a specific length' do
359
- out, err = capture_io do
360
- assert_match /[a-zA-Z0-9]{32}/, utils.generate_random_id(32)
375
+ _, err = capture_io do
376
+ assert_match(/[a-zA-Z0-9]{32}/, utils.generate_random_id(32) )
361
377
  end
362
378
  assert_match "WebUtils::generate_random_id is deprecated", err
363
379
  end
@@ -508,13 +524,13 @@ describe WebUtils do
508
524
  assert_equal 2800, utils.parse_price('28')
509
525
  end
510
526
  it 'Ignores visual help but works with negative prices' do
511
- assert_equal -1234567890, utils.parse_price(' £-12,345,678.90 ')
527
+ assert_equal(-1234567890, utils.parse_price(' £-12,345,678.90 ') )
512
528
  end
513
529
  it 'Parses comma-based prices - french/german style' do
514
530
  assert_equal 2390, utils.parse_price('23,90')
515
531
  assert_equal 2390, utils.parse_price('23,9')
516
532
  assert_equal 2000000, utils.parse_price('20.000')
517
- assert_equal -1234567890, utils.parse_price(' £-12.345.678,90 ')
533
+ assert_equal(-1234567890, utils.parse_price(' £-12.345.678,90 ') )
518
534
  end
519
535
  it 'Raises when argument is not string' do
520
536
  assert_raises(TypeError) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mickael Riga
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-17 00:00:00.000000000 Z
11
+ date: 2019-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack