kebab 1.0.2

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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/Changelog.md +99 -0
  4. data/MIT-LICENSE +19 -0
  5. data/README.md +26 -0
  6. data/Rakefile +34 -0
  7. data/lib/kebab.rb +18 -0
  8. data/lib/kebab/identifier.rb +294 -0
  9. data/lib/kebab/transliterator/base.rb +110 -0
  10. data/lib/kebab/transliterator/bulgarian.rb +27 -0
  11. data/lib/kebab/transliterator/cyrillic.rb +108 -0
  12. data/lib/kebab/transliterator/danish.rb +15 -0
  13. data/lib/kebab/transliterator/german.rb +15 -0
  14. data/lib/kebab/transliterator/greek.rb +77 -0
  15. data/lib/kebab/transliterator/hindi.rb +137 -0
  16. data/lib/kebab/transliterator/latin.rb +199 -0
  17. data/lib/kebab/transliterator/macedonian.rb +29 -0
  18. data/lib/kebab/transliterator/norwegian.rb +14 -0
  19. data/lib/kebab/transliterator/romanian.rb +13 -0
  20. data/lib/kebab/transliterator/russian.rb +22 -0
  21. data/lib/kebab/transliterator/serbian.rb +34 -0
  22. data/lib/kebab/transliterator/spanish.rb +9 -0
  23. data/lib/kebab/transliterator/swedish.rb +16 -0
  24. data/lib/kebab/transliterator/turkish.rb +8 -0
  25. data/lib/kebab/transliterator/ukrainian.rb +30 -0
  26. data/lib/kebab/transliterator/vietnamese.rb +143 -0
  27. data/lib/kebab/utf8/active_support_proxy.rb +26 -0
  28. data/lib/kebab/utf8/dumb_proxy.rb +49 -0
  29. data/lib/kebab/utf8/java_proxy.rb +22 -0
  30. data/lib/kebab/utf8/mappings.rb +193 -0
  31. data/lib/kebab/utf8/proxy.rb +125 -0
  32. data/lib/kebab/utf8/unicode_proxy.rb +23 -0
  33. data/lib/kebab/version.rb +5 -0
  34. data/spec/kebab_spec.rb +155 -0
  35. data/spec/spec_helper.rb +45 -0
  36. data/spec/transliterators/base_spec.rb +16 -0
  37. data/spec/transliterators/bulgarian_spec.rb +20 -0
  38. data/spec/transliterators/danish_spec.rb +17 -0
  39. data/spec/transliterators/german_spec.rb +17 -0
  40. data/spec/transliterators/greek_spec.rb +17 -0
  41. data/spec/transliterators/hindi_spec.rb +17 -0
  42. data/spec/transliterators/latin_spec.rb +9 -0
  43. data/spec/transliterators/macedonian_spec.rb +9 -0
  44. data/spec/transliterators/norwegian_spec.rb +18 -0
  45. data/spec/transliterators/polish_spec.rb +14 -0
  46. data/spec/transliterators/romanian_spec.rb +19 -0
  47. data/spec/transliterators/russian_spec.rb +9 -0
  48. data/spec/transliterators/serbian_spec.rb +25 -0
  49. data/spec/transliterators/spanish_spec.rb +13 -0
  50. data/spec/transliterators/swedish_spec.rb +18 -0
  51. data/spec/transliterators/turkish_spec.rb +24 -0
  52. data/spec/transliterators/ukrainian_spec.rb +88 -0
  53. data/spec/transliterators/vietnamese_spec.rb +18 -0
  54. data/spec/utf8_proxy_spec.rb +53 -0
  55. metadata +167 -0
@@ -0,0 +1,155 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Identifier do
5
+ using Kebab
6
+
7
+ it "should respond_to :empty?" do
8
+ expect("".to_slug).to respond_to(:empty?)
9
+ end
10
+
11
+ %w[approximate_ascii clean downcase word_chars normalize to_ascii upcase with_dashes].each do |method|
12
+ describe "##{method}" do
13
+ it "should work with invalid UTF-8 strings" do
14
+ expect {"\x93abc".to_slug.send method}.not_to raise_exception
15
+ end
16
+ end
17
+ end
18
+
19
+ describe "#word_chars" do
20
+ it "word_chars! should leave only letters and spaces" do
21
+ string = "a*$%^$@!@b$%^&*()*!c"
22
+ expect(string.to_slug.word_chars!).to match(/[a-z ]*/i)
23
+ end
24
+ end
25
+
26
+ describe "#transliterate" do
27
+ it "should transliterate to ascii" do
28
+ (0xC0..0x17E).to_a.each do |codepoint|
29
+ ss = [codepoint].pack("U*").to_slug
30
+ expect(ss.approximate_ascii!).to match(/[\x0-\x7f]/)
31
+ end
32
+ end
33
+
34
+ it "should transliterate uncomposed utf8" do
35
+ string = [117, 776].pack("U*") # "ü" as ASCII "u" plus COMBINING DIAERESIS
36
+ expect(string.to_slug.approximate_ascii).to eql("u")
37
+ end
38
+
39
+ it "should transliterate using multiple transliterators" do
40
+ string = "свободное režģis"
41
+ expect(string.to_slug.approximate_ascii(:latin, :russian)).to eql("svobodnoe rezgis")
42
+ end
43
+ end
44
+
45
+ describe "#downcase" do
46
+ it "should lowercase strings" do
47
+ expect("FELIZ AÑO".to_slug.downcase).to eql("feliz año")
48
+ end
49
+ end
50
+
51
+ describe "#upcase" do
52
+ it "should uppercase strings" do
53
+ expect("feliz año".to_slug.upcase).to eql("FELIZ AÑO")
54
+ end
55
+ end
56
+
57
+ describe "#normalize" do
58
+
59
+ it "should allow passing locale as key for :transliterate" do
60
+ expect("ö".to_slug.clean.normalize(:transliterate => :german)).to eql("oe")
61
+ end
62
+
63
+ it "should replace whitespace with dashes" do
64
+ expect("a b".to_slug.clean.normalize).to eql("a-b")
65
+ end
66
+
67
+ it "should replace multiple spaces with 1 dash" do
68
+ expect("a b".to_slug.clean.normalize).to eql("a-b")
69
+ end
70
+
71
+ it "should replace multiple dashes with 1 dash" do
72
+ expect("male - female".to_slug.normalize).to eql("male-female")
73
+ end
74
+
75
+ it "should strip trailing space" do
76
+ expect("ab ".to_slug.normalize).to eql("ab")
77
+ end
78
+
79
+ it "should strip leading space" do
80
+ expect(" ab".to_slug.normalize).to eql("ab")
81
+ end
82
+
83
+ it "should strip trailing slashes" do
84
+ expect("ab-".to_slug.normalize).to eql("ab")
85
+ end
86
+
87
+ it "should strip leading slashes" do
88
+ expect("-ab".to_slug.normalize).to eql("ab")
89
+ end
90
+
91
+ it "should not modify valid name strings" do
92
+ expect("a-b-c-d".to_slug.normalize).to eql("a-b-c-d")
93
+ end
94
+
95
+ it "should not convert underscores" do
96
+ expect("hello_world".to_slug.normalize).to eql("hello_world")
97
+ end
98
+
99
+ it "should work with non roman chars" do
100
+ expect("検 索".to_slug.normalize).to eql("検-索")
101
+ end
102
+
103
+ context "with to_ascii option" do
104
+ it "should approximate and strip non ascii" do
105
+ ss = "カタカナ: katakana is über cool".to_slug
106
+ expect(ss.normalize(:to_ascii => true)).to eql("katakana-is-uber-cool")
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "#truncate_bytes" do
112
+ it "should by byte length" do
113
+ expect("üa".to_slug.truncate_bytes(2)).to eql("ü")
114
+ expect("üa".to_slug.truncate_bytes(1)).to eql("")
115
+ expect("üa".to_slug.truncate_bytes(100)).to eql("üa")
116
+ expect("üéøá".to_slug.truncate_bytes(3)).to eql("ü")
117
+ end
118
+ end
119
+
120
+ describe "#truncate" do
121
+ it "should truncate by char length" do
122
+ expect("üa".to_slug.truncate(2)).to eql("üa")
123
+ expect("üa".to_slug.truncate(1)).to eql("ü")
124
+ expect("üa".to_slug.truncate(100)).to eql("üa")
125
+ end
126
+ end
127
+
128
+ describe "#with_dashes" do
129
+ it "should not change byte size when replacing spaces" do
130
+ expect("".to_slug.with_dashes.bytesize).to eql(0)
131
+ expect(" ".to_slug.with_dashes.bytesize).to eql(1)
132
+ expect("-abc-".to_slug.with_dashes.bytesize).to eql(5)
133
+ expect(" abc ".to_slug.with_dashes.bytesize).to eql(5)
134
+ expect(" a bc ".to_slug.with_dashes.bytesize).to eql(7)
135
+ end
136
+ end
137
+
138
+ describe "#to_ruby_method" do
139
+ it "should get a string suitable for use as a ruby method" do
140
+ expect("¿¿¿hello... world???".to_slug.to_ruby_method).to eql("hello_world?")
141
+ expect("カタカナ: katakana is über cool".to_slug.to_ruby_method).to eql("katakana_is_uber_cool")
142
+ expect("カタカナ: katakana is über cool!".to_slug.to_ruby_method).to eql("katakana_is_uber_cool!")
143
+ expect("カタカナ: katakana is über cool".to_slug.to_ruby_method(false)).to eql("katakana_is_uber_cool")
144
+ end
145
+
146
+ it "should optionally remove trailing punctuation" do
147
+ expect("¿¿¿hello... world???".to_slug.to_ruby_method(false)).to eql("hello_world")
148
+ end
149
+
150
+ it "should raise an error when it would generate an impossible method name" do
151
+ # "1".to_identifier.to_ruby_method
152
+ expect {"1".to_identifier.to_ruby_method}.to raise_error(Kebab::Identifier::Error)
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+
3
+ if ENV['COV']
4
+ require 'simplecov'
5
+ SimpleCov.start
6
+ end
7
+
8
+ require 'bundler/setup'
9
+ require 'kebab'
10
+
11
+ shared_examples_for "a latin transliterator" do
12
+ let(:t) { described_class.instance }
13
+
14
+ it "should transliterate latin characters" do
15
+ string = (0xC0..0x17E).to_a.pack("U*")
16
+ expect(t.transliterate(string)).to match(/[\x0-\x7f]/)
17
+ end
18
+ end
19
+
20
+ shared_examples_for "a cyrillic transliterator" do
21
+ let(:t) { described_class.instance }
22
+
23
+ it "should transliterate cyrillic characters" do
24
+ string = "Славься, Отечество наше свободное"
25
+ expect(t.transliterate(string)).to match(/[\x0-\x7f]/)
26
+ end
27
+ end
28
+
29
+ shared_examples_for "a greek transliterator" do
30
+ let(:t) { described_class.instance }
31
+
32
+ it "should transliterate greek characters" do
33
+ string = "Γερμανία"
34
+ expect(t.transliterate(string)).to match(/[\x0-\x7f]/)
35
+ end
36
+ end
37
+
38
+ shared_examples_for "a hindi transliterator" do
39
+ let(:t) { described_class.instance }
40
+
41
+ it "should transliterate hindi characters" do
42
+ string = "आदित्य तापड़िया"
43
+ expect(t.transliterate(string)).to match(/[\x0-\x7f]/)
44
+ end
45
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Base do
5
+
6
+ let(:t) {Kebab::Transliterator::Base.instance}
7
+
8
+ it "should transliterate 'smart' quotes" do
9
+ expect(t.transliterate("’")).to eql("'")
10
+ end
11
+
12
+ it "should transliterate non-breaking spaces" do
13
+ expect(t.transliterate("\xc2\xa0")).to eql(" ")
14
+ end
15
+
16
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Bulgarian do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a cyrillic transliterator"
8
+
9
+ it "should transliterate Cyrillic characters" do
10
+ examples = {
11
+ "Ютия" => "Iutiia",
12
+ "Чушка" => "Chushka",
13
+ "кьорав" => "kiorav",
14
+ "Щъркел" => "Shturkel",
15
+ "полицай" => "policai"
16
+ }
17
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
18
+ end
19
+
20
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Danish do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ it "should transliterate various characters" do
10
+ examples = {
11
+ "Ærøskøbing" => "Aeroeskoebing",
12
+ "Årslev" => "Aarslev"
13
+ }
14
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::German do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ it "should transliterate Eszett" do
10
+ expect(t.transliterate("ß")).to eql("ss")
11
+ end
12
+
13
+ it "should transliterate vowels with umlauts" do
14
+ expect(t.transliterate("üöä")).to eql("ueoeae")
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Greek do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a greek transliterator"
8
+
9
+ it "should transliterate various characters" do
10
+ examples = {
11
+ "Γερμανία" => "Germania",
12
+ "Αυστρία" => "Aystria",
13
+ "Ιταλία" => "Italia"
14
+ }
15
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Hindi do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a hindi transliterator"
8
+
9
+ it "should transliterate hindi characters" do
10
+ examples = {
11
+ "आदित्य" => "aadity",
12
+ "सबरीमाला करवाना पायसम" => "sbriimaalaa krvaanaa paaysm",
13
+ "सक्रांति आँख" => "skraanti aankh"
14
+ }
15
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Latin do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Macedonian do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a cyrillic transliterator"
8
+
9
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Norwegian do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ it "should transliterate various characters" do
10
+ examples = {
11
+ "Øivind" => "Oeivind",
12
+ "Bø" => "Boe",
13
+ "Åre" => "Aare",
14
+ "Håkon" => "Haakon"
15
+ }
16
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Romanian do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ it "should transliterate various characters" do
10
+ expect(t.transliterate("ĄąĆćĘꣳŃńÓóŚśŹźŻż")).to eql("AaCcEeLlNnOoSsZzZz")
11
+ end
12
+
13
+ end
14
+
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Romanian do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ it "should transliterate various characters" do
10
+ examples = {
11
+ "Iași" => "Iasi",
12
+ "Mehedinți" => "Mehedinti",
13
+ "Țară" => "Tara",
14
+ "Șanț" => "Sant"
15
+ }
16
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
17
+ end
18
+
19
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Russian do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a cyrillic transliterator"
8
+
9
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Serbian do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+ it_behaves_like "a cyrillic transliterator"
9
+
10
+ it "should transliterate Latin characters" do
11
+ examples = {
12
+ "Ðorđe" => "Djordje",
13
+ "Inđija" => "Indjija",
14
+ "Četiri" => "Chetiri",
15
+ "četiri" => "chetiri",
16
+ "Škola" => "Shkola",
17
+ "škola" => "shkola",
18
+ "Ђорђе" => "Djordje",
19
+ "Инђија" => "Indjija",
20
+ "Школа" => "Shkola",
21
+ }
22
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
23
+ end
24
+
25
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Spanish do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ it "should transliterate ñ" do
10
+ expect(t.transliterate("ñ")).to eql("ni")
11
+ end
12
+
13
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ require File.expand_path("../../spec_helper", __FILE__)
3
+
4
+ describe Kebab::Transliterator::Swedish do
5
+
6
+ let(:t) { described_class.instance }
7
+ it_behaves_like "a latin transliterator"
8
+
9
+ it "should transliterate various characters" do
10
+ examples = {
11
+ "Räksmörgås" => "Raeksmoergaas",
12
+ "Öre" => "Oere",
13
+ "Åre" => "Aare",
14
+ "Älskar" => "Aelskar"
15
+ }
16
+ examples.each {|k, v| expect(t.transliterate(k)).to eql(v)}
17
+ end
18
+ end