web-utils 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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