al 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2fa42cadb858988b7a7833de0e82584a1a396023
4
- data.tar.gz: 9e455e216ad7176e2529ffff67a74d7f83efc3c2
3
+ metadata.gz: 916f2172f8334bd4022beba1200fbadc5ef02f99
4
+ data.tar.gz: 9960379dacc8cb84b26c05da2a5b3e46ea6e5b0e
5
5
  SHA512:
6
- metadata.gz: 6f6bf956fe3dcd1b41cd41521eb04898631c5ab8252c86a1cf8c1abf33dbd7f9b2f317f5f9b8a9b7c806298a09bfca171f26185009c9f877f6f08cedf3f6a5ae
7
- data.tar.gz: 6fbd3ad62290013dbd3216aed8112f5df4ac38fa65d4e0f5e1ed7dd2e5c0698837412183395f6d872c5a68d9ba4c5bd3ee1498def9b19bcbc7ef99e7f0119fcd
6
+ metadata.gz: 99b589489d1089ae744d4ef4d8b455323958a1810a4a738f6b3ab48599c373d9c5ba7b613ae375485ca5fe44fd9f47b12142f2621c714eca29b6d212156a0f5c
7
+ data.tar.gz: 133b27b1395a6fb3d3de09fa142b3739b6ee2d52fe630045a801038c083fb4c11633ede447c348aa9f38b42a8006bfd27ed6c934491f1f4bf688515bd0d897ce
data/lib/al.rb CHANGED
@@ -1,21 +1,25 @@
1
1
  class Al
2
- def initialize(tag = nil, val = nil)
3
- @languages = { DEFAULT => [tag, val] }
2
+ def initialize(tag = nil, value = nil)
3
+ unless tag.nil?
4
+ tag = tag.downcase
5
+ end
6
+
7
+ @languages = { "*" => [tag, value] }
4
8
 
5
- if tag && val
6
- self[tag] = val
9
+ if tag && value
10
+ self[tag] = value
7
11
  end
8
12
  end
9
13
 
10
- def []=(tag, val)
14
+ def []=(tag, value)
11
15
  tag = preprocess(tag)
12
16
 
13
- tag.split(DASH).each_with_object("") do |bit, key|
14
- key.concat("-#{bit}")
15
- @languages[key[1..-1]] ||= [tag, val]
17
+ tag.split("-").inject do |key, bit|
18
+ @languages[key] ||= [tag, value]
19
+ "#{key}-#{bit}"
16
20
  end
17
21
 
18
- @languages[tag] = [tag, val] # ensure xx overwrites a previous xx-yy
22
+ @languages[tag] = [tag, value] # ensure xx overwrites a previous xx-yy
19
23
  end
20
24
 
21
25
  def [](tag)
@@ -23,97 +27,72 @@ class Al
23
27
  end
24
28
 
25
29
  def pick(header)
26
- unless header
27
- return @languages[DEFAULT]
28
- end
29
-
30
- high = 0.0
31
- best = nil
32
-
33
- preprocess(header).split(COMMA).each do |tag|
34
- len = tag.size
35
- sem = tag.index(SEMICOLON) || len
36
- pos = sem
30
+ find(header) do |tag|
31
+ length = tag.length
32
+ dash_index = length
37
33
 
38
- while pos
39
- attempt = tag[0, pos]
40
- result = @languages[attempt]
34
+ while dash_index
35
+ result = @languages[tag[0, dash_index]]
41
36
 
42
37
  if result
43
- quality = quality(tag, sem, len)
44
-
45
- if quality > high
46
- high = quality
47
- best = result
48
-
49
- if high >= 1.0
50
- return best
51
- end
52
-
53
- break
54
- end
38
+ break result
55
39
  end
56
40
 
57
- pos = tag.rindex(DASH, -(len - pos) - 1)
41
+ dash_index = tag.rindex("-".freeze, dash_index - length - 1)
58
42
  end
59
43
  end
60
-
61
- return best || @languages[DEFAULT]
62
44
  end
63
45
 
64
46
  def strict_pick(header)
65
- unless header
66
- return @languages[DEFAULT]
67
- end
47
+ find(header) { |tag| @languages[tag] }
48
+ end
49
+
50
+ private
51
+
52
+ def find(header, &block)
53
+ best_quality = 0.0
54
+ best_result = nil
55
+
56
+ preprocess(header.to_s).split(",".freeze).each do |language_range|
57
+ tag, q = language_range.split(";".freeze, 2)
68
58
 
69
- high = 0.0
70
- best = nil
71
-
72
- preprocess(header).split(COMMA).each do |tag|
73
- sem = tag.index(SEMICOLON) || tag.size
74
- result = @languages[tag[0, sem]]
75
-
76
- if result
77
- len = tag.size
78
- sem = tag.index(SEMICOLON) || len
79
- quality = quality(tag, sem, len)
80
-
81
- if quality > high
82
- high = quality
83
- best = result
84
-
85
- if high >= 1.0
86
- return best
87
- end
59
+ unless tag
60
+ next
61
+ end
62
+
63
+ result = yield(tag)
64
+
65
+ unless result
66
+ next
67
+ end
68
+
69
+ quality = quality(q)
70
+
71
+ if quality > best_quality
72
+ best_quality = quality
73
+ best_result = result
74
+
75
+ if quality >= 1.0
76
+ break result
88
77
  end
89
78
  end
90
79
  end
91
80
 
92
- return best || @languages[DEFAULT]
81
+ return best_result || @languages["*".freeze]
93
82
  end
94
83
 
95
- private
96
-
97
- SPACE = " ".freeze
98
- EMPTY = "".freeze
99
-
100
- def preprocess(s)
101
- result = s.tr(SPACE, EMPTY)
84
+ def preprocess(header)
85
+ result = header.delete(" ".freeze)
102
86
  result.downcase!
103
87
 
104
88
  return result
105
89
  end
106
90
 
107
- def quality(tag, sem, len)
108
- q = tag[sem + 3, 10]
91
+ def quality(q)
92
+ if q.nil? || q.size < 2
93
+ return 1.0
94
+ end
109
95
 
110
- return q ? Float(q) : 1.0
111
- rescue ArgumentError
112
- 0.0
96
+ return q[2, 10].to_f
113
97
  end
114
-
115
- DEFAULT = "*".freeze
116
- COMMA = ",".freeze
117
- SEMICOLON = ";".freeze
118
- DASH = "-".freeze
119
98
  end
@@ -1,5 +1,6 @@
1
1
  require "al"
2
2
  require "cutest"
3
+ require "securerandom"
3
4
 
4
5
  test "no input" do
5
6
  al = Al.new("en-gb", "british english")
@@ -60,3 +61,13 @@ test "invalid quality values" do
60
61
  assert_equal al.pick("en-gb;q=.9, en-us;q=0.8"), ["en-gb", "british english"]
61
62
  assert_equal al.pick("en-gb;q=aaa, en-us;q=0.8"), ["en-us", "american english"]
62
63
  end
64
+
65
+ test "gibberish" do
66
+ al = Al.new("en-gb", "british english")
67
+
68
+ assert 1000.times.all? {
69
+ s = SecureRandom.random_bytes rand(1000)
70
+
71
+ al.pick(s) || raise("failed on: #{s}")
72
+ }
73
+ end
@@ -47,4 +47,9 @@ test "default value" do
47
47
  al["en-GB"] = "british english"
48
48
 
49
49
  assert_equal al.pick("en-us"), ["en", "english"]
50
+
51
+ al = Al.new("EN", "english")
52
+ al["en-GB"] = "british english"
53
+
54
+ assert_equal al.pick("en-us"), ["en", "english"]
50
55
  end
@@ -1,5 +1,6 @@
1
1
  require "al"
2
2
  require "cutest"
3
+ require "securerandom"
3
4
 
4
5
  test "no input" do
5
6
  al = Al.new("en-gb", "british english")
@@ -60,3 +61,13 @@ test "invalid quality values" do
60
61
  assert_equal al.strict_pick("en-gb;q=.9, en-us;q=0.8"), ["en-gb", "british english"]
61
62
  assert_equal al.strict_pick("en-gb;q=aaa, en-us;q=0.8"), ["en-us", "american english"]
62
63
  end
64
+
65
+ test "gibberish" do
66
+ al = Al.new("en-gb", "british english")
67
+
68
+ assert 1000.times.all? {
69
+ s = SecureRandom.random_bytes rand(1000)
70
+
71
+ al.strict_pick(s) || raise("failed on: #{s}")
72
+ }
73
+ end
@@ -46,5 +46,10 @@ test "default value" do
46
46
  al = Al.new("en", "english")
47
47
  al["en-GB"] = "british english"
48
48
 
49
- assert_equal al.pick("en-us"), ["en", "english"]
49
+ assert_equal al.strict_pick("en-us"), ["en", "english"]
50
+
51
+ al = Al.new("EN", "english")
52
+ al["en-GB"] = "british english"
53
+
54
+ assert_equal al.strict_pick("en-us"), ["en", "english"]
50
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: al
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jip van Reijsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-25 00:00:00.000000000 Z
11
+ date: 2016-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cutest
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
64
  version: '0'
65
65
  requirements: []
66
66
  rubyforge_project:
67
- rubygems_version: 2.4.5
67
+ rubygems_version: 2.5.1
68
68
  signing_key:
69
69
  specification_version: 4
70
70
  summary: Al stands for Accept-Language
@@ -73,4 +73,3 @@ test_files:
73
73
  - test/pick_test.rb
74
74
  - test/strict_parse_test.rb
75
75
  - test/strict_pick_test.rb
76
- has_rdoc: