ffi-icu 0.5.2 → 0.6.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -0
  3. data/LICENSE +1 -1
  4. data/README.md +21 -51
  5. data/Rakefile +4 -5
  6. data/ffi-icu.gemspec +34 -25
  7. data/lib/ffi-icu/break_iterator.rb +19 -18
  8. data/lib/ffi-icu/chardet.rb +12 -13
  9. data/lib/ffi-icu/collation.rb +62 -59
  10. data/lib/ffi-icu/duration_formatting.rb +293 -267
  11. data/lib/ffi-icu/lib/util.rb +10 -10
  12. data/lib/ffi-icu/lib.rb +273 -202
  13. data/lib/ffi-icu/locale.rb +14 -10
  14. data/lib/ffi-icu/normalization.rb +7 -7
  15. data/lib/ffi-icu/normalizer.rb +14 -8
  16. data/lib/ffi-icu/number_formatting.rb +41 -27
  17. data/lib/ffi-icu/time_formatting.rb +116 -93
  18. data/lib/ffi-icu/transliteration.rb +19 -19
  19. data/lib/ffi-icu/uchar.rb +14 -17
  20. data/lib/ffi-icu/version.rb +3 -1
  21. data/lib/ffi-icu.rb +16 -17
  22. metadata +35 -71
  23. data/.document +0 -5
  24. data/.gitignore +0 -23
  25. data/.rspec +0 -2
  26. data/.travis.yml +0 -28
  27. data/benchmark/detect.rb +0 -14
  28. data/benchmark/shared.rb +0 -17
  29. data/build_icu.sh +0 -53
  30. data/lib/ffi-icu/core_ext/string.rb +0 -9
  31. data/spec/break_iterator_spec.rb +0 -77
  32. data/spec/chardet_spec.rb +0 -42
  33. data/spec/collation_spec.rb +0 -84
  34. data/spec/duration_formatting_spec.rb +0 -143
  35. data/spec/lib/version_info_spec.rb +0 -20
  36. data/spec/lib_spec.rb +0 -63
  37. data/spec/locale_spec.rb +0 -280
  38. data/spec/normalization_spec.rb +0 -22
  39. data/spec/normalizer_spec.rb +0 -57
  40. data/spec/number_formatting_spec.rb +0 -79
  41. data/spec/spec_helper.rb +0 -13
  42. data/spec/time_spec.rb +0 -198
  43. data/spec/transliteration_spec.rb +0 -36
  44. data/spec/uchar_spec.rb +0 -34
  45. data/test.c +0 -56
@@ -1,79 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module ICU
4
- module NumberFormatting
5
- describe 'NumberFormatting' do
6
- it 'should format a simple integer' do
7
- expect(NumberFormatting.format_number("en", 1)).to eq("1")
8
- expect(NumberFormatting.format_number("en", 1_000)).to eq("1,000")
9
- expect(NumberFormatting.format_number("de-DE", 1_000_000)).to eq("1.000.000")
10
- end
11
-
12
- it 'should format a float' do
13
- expect(NumberFormatting.format_number("en", 1.0)).to eq("1")
14
- expect(NumberFormatting.format_number("en", 1.123)).to eq("1.123")
15
- expect(NumberFormatting.format_number("en", 1_000.1238)).to eq("1,000.124")
16
- expect(NumberFormatting.format_number("en", 1_000.1238, max_fraction_digits: 4)).to eq("1,000.1238")
17
- NumberFormatting.set_default_options(fraction_digits: 5)
18
- expect(NumberFormatting.format_number("en", 1_000.1238)).to eq("1,000.12380")
19
- NumberFormatting.clear_default_options
20
- end
21
-
22
- it 'should format a decimal' do
23
- expect(NumberFormatting.format_number("en", BigDecimal("10000.123"))).to eq("10,000.123")
24
- end
25
-
26
- it 'should format a currency' do
27
- expect(NumberFormatting.format_currency("en", 123.45, 'USD')).to eq("$123.45")
28
- expect(NumberFormatting.format_currency("en", 123_123.45, 'USD')).to eq("$123,123.45")
29
- expect(NumberFormatting.format_currency("de-DE", 123_123.45, 'EUR')).to eq("123.123,45\u{A0}€")
30
- end
31
-
32
- it 'should format a percent' do
33
- expect(NumberFormatting.format_percent("en", 1.1)).to eq("110%")
34
- expect(NumberFormatting.format_percent("da", 0.15)).to eq("15\u{A0}%")
35
- expect(NumberFormatting.format_percent("da", -0.1545, max_fraction_digits: 10)).to eq("-15,45\u{A0}%")
36
- end
37
-
38
- it 'should spell numbers' do
39
- expect(NumberFormatting.spell("en_US", 1_000)).to eq('one thousand')
40
- expect(NumberFormatting.spell("de-DE", 123.456)).to eq("ein\u{AD}hundert\u{AD}drei\u{AD}und\u{AD}zwanzig Komma vier fünf sechs")
41
- end
42
-
43
- it 'should be able to re-use number formatter objects' do
44
- numf = NumberFormatting.create('fr-CA')
45
- expect(numf.format(1_000)).to eq("1\u{A0}000")
46
- expect(numf.format(1_000.123)).to eq("1\u{A0}000,123")
47
- end
48
-
49
- it 'should be able to re-use currency formatter objects' do
50
- curf = NumberFormatting.create('en-US', :currency)
51
- expect(curf.format(1_000.12, 'USD')).to eq("$1,000.12")
52
- end
53
-
54
- it 'should allow for various styles of currency formatting if the version is new enough' do
55
- if ICU::Lib.version.to_a.first >= 53
56
- curf = NumberFormatting.create('en-US', :currency, style: :iso)
57
- expected = if ICU::Lib.version.to_a.first >= 62
58
- "USD\u00A01,000.12"
59
- else
60
- "USD1,000.12"
61
- end
62
- expect(curf.format(1_000.12, 'USD')).to eq(expected)
63
- curf = NumberFormatting.create('en-US', :currency, style: :plural)
64
- expect(curf.format(1_000.12, 'USD')).to eq("1,000.12 US dollars")
65
- expect { NumberFormatting.create('en-US', :currency, style: :fake) }.to raise_error(StandardError)
66
- else
67
- curf = NumberFormatting.create('en-US', :currency, style: :default)
68
- expect(curf.format(1_000.12, 'USD')).to eq('$1,000.12')
69
- expect { NumberFormatting.create('en-US', :currency, style: :iso) }.to raise_error(StandardError)
70
- end
71
- end
72
-
73
- it 'should format a bignum' do
74
- str = NumberFormatting.format_number("en", 1_000_000_000_000_000_000_000_000_000_000_000_000_000)
75
- expect(str).to eq('1,000,000,000,000,000,000,000,000,000,000,000,000,000')
76
- end
77
- end
78
- end # NumberFormatting
79
- end # ICU
data/spec/spec_helper.rb DELETED
@@ -1,13 +0,0 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
-
4
- require "rubygems"
5
- require 'ffi-icu'
6
- require 'rspec'
7
-
8
- RSpec.configure do |config|
9
-
10
- if ENV['TRAVIS']
11
- config.filter_run_excluding broken: true
12
- end
13
- end
data/spec/time_spec.rb DELETED
@@ -1,198 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module ICU
4
- describe TimeFormatting do
5
- describe 'the TimeFormatting ' do
6
- t0 = Time.at(1226499676) # in TZ=Europe/Prague Time.mktime(2008, 11, 12, 15, 21, 16)
7
- t1 = Time.at(1224890117) # in TZ=Europe/Prague Time.mktime(2008, 10, 25, 01, 15, 17)
8
- t2 = Time.at(1224893778) # in TZ=Europe/Prague Time.mktime(2008, 10, 25, 02, 16, 18)
9
- t3 = Time.at(1224897439) # in TZ=Europe/Prague Time.mktime(2008, 10, 25, 03, 17, 19)
10
- t4 = Time.at(1224901100) # in TZ=Europe/Prague Time.mktime(2008, 10, 25, 04, 18, 20)
11
- t5 = Time.at(1206750921) # in TZ=Europe/Prague Time.mktime(2008, 03, 29, 01, 35, 21)
12
- t6 = Time.at(1206754582) # in TZ=Europe/Prague Time.mktime(2008, 03, 29, 02, 36, 22)
13
- t7 = Time.at(1206758243) # in TZ=Europe/Prague Time.mktime(2008, 03, 29, 03, 37, 23)
14
- t8 = Time.at(1206761904) # in TZ=Europe/Prague Time.mktime(2008, 03, 29, 04, 38, 24)
15
-
16
- f1 = TimeFormatting.create(:locale => 'cs_CZ', :zone => 'Europe/Prague', :date => :long , :time => :long, :tz_style => :localized_long)
17
- it 'check date_format for lang=cs_CZ' do
18
- expect(f1.date_format(true)).to eq("d. MMMM y H:mm:ss ZZZZ")
19
- expect(f1.date_format(false)).to eq("d. MMMM y H:mm:ss ZZZZ")
20
- end
21
-
22
- it "for lang=cs_CZ zone=Europe/Prague" do
23
- expect(f1).to be_an_instance_of TimeFormatting::DateTimeFormatter
24
- expect(f1.format(t0)).to eq("12. listopadu 2008 15:21:16 GMT+01:00")
25
- expect(f1.format(t1)).to eq("25. října 2008 1:15:17 GMT+02:00")
26
- expect(f1.format(t2)).to eq("25. října 2008 2:16:18 GMT+02:00")
27
- expect(f1.format(t3)).to eq("25. října 2008 3:17:19 GMT+02:00")
28
- expect(f1.format(t4)).to eq("25. října 2008 4:18:20 GMT+02:00")
29
- expect(f1.format(t5)).to eq("29. března 2008 1:35:21 GMT+01:00")
30
- expect(f1.format(t6)).to eq("29. března 2008 2:36:22 GMT+01:00")
31
- expect(f1.format(t7)).to eq("29. března 2008 3:37:23 GMT+01:00")
32
- expect(f1.format(t8)).to eq("29. března 2008 4:38:24 GMT+01:00")
33
- end
34
-
35
- f2 = TimeFormatting.create(:locale => 'en_US', :zone => 'Europe/Moscow', :date => :short , :time => :long, :tz_style => :generic_location)
36
- cldr_version = Lib.cldr_version.to_s
37
- en_tz = "Moscow Time"
38
- en_sep = ","
39
- if cldr_version <= "2.0.1"
40
- en_tz = "Russia Time (Moscow)"
41
- en_sep = ""
42
- end
43
-
44
- en_exp = "M/d/yy#{en_sep} h:mm:ss a VVVV"
45
- it 'check date_format for lang=en_US' do
46
- expect(f2.date_format(true)).to eq(en_exp)
47
- expect(f2.date_format(false)).to eq(en_exp)
48
- end
49
-
50
- it "lang=en_US zone=Europe/Moscow" do
51
- expect(f2.format(t0)).to eq("11/12/08#{en_sep} 5:21:16 PM #{en_tz}")
52
- expect(f2.format(t1)).to eq("10/25/08#{en_sep} 3:15:17 AM #{en_tz}")
53
- expect(f2.format(t2)).to eq("10/25/08#{en_sep} 4:16:18 AM #{en_tz}")
54
- expect(f2.format(t3)).to eq("10/25/08#{en_sep} 5:17:19 AM #{en_tz}")
55
- expect(f2.format(t4)).to eq("10/25/08#{en_sep} 6:18:20 AM #{en_tz}")
56
- expect(f2.format(t5)).to eq("3/29/08#{en_sep} 3:35:21 AM #{en_tz}")
57
- expect(f2.format(t6)).to eq("3/29/08#{en_sep} 4:36:22 AM #{en_tz}")
58
- expect(f2.format(t7)).to eq("3/29/08#{en_sep} 5:37:23 AM #{en_tz}")
59
- expect(f2.format(t8)).to eq("3/29/08#{en_sep} 6:38:24 AM #{en_tz}")
60
- end
61
-
62
- f3 = TimeFormatting.create(:locale => 'de_DE', :zone => 'Africa/Dakar', :date => :short , :time => :long)
63
- ge_sep = ""
64
- if cldr_version >= "27.0.1"
65
- ge_sep = ","
66
- end
67
-
68
- ge_exp = "dd.MM.yy#{ge_sep} HH:mm:ss z"
69
- it 'check date_format for lang=de_DE' do
70
- expect(f3.date_format(true)).to eq(ge_exp)
71
- expect(f3.date_format(false)).to eq(ge_exp)
72
- end
73
-
74
- it "lang=de_DE zone=Africa/Dakar" do
75
- expect(f3.format(t0)).to eq("12.11.08#{ge_sep} 14:21:16 GMT")
76
- expect(f3.format(t1)).to eq("24.10.08#{ge_sep} 23:15:17 GMT")
77
- expect(f3.format(t2)).to eq("25.10.08#{ge_sep} 00:16:18 GMT")
78
- expect(f3.format(t3)).to eq("25.10.08#{ge_sep} 01:17:19 GMT")
79
- expect(f3.format(t4)).to eq("25.10.08#{ge_sep} 02:18:20 GMT")
80
- expect(f3.format(t5)).to eq("29.03.08#{ge_sep} 00:35:21 GMT")
81
- expect(f3.format(t6)).to eq("29.03.08#{ge_sep} 01:36:22 GMT")
82
- expect(f3.format(t7)).to eq("29.03.08#{ge_sep} 02:37:23 GMT")
83
- expect(f3.format(t8)).to eq("29.03.08#{ge_sep} 03:38:24 GMT")
84
- end
85
-
86
- context 'skeleton pattern' do
87
- f4 = TimeFormatting.create(:locale => 'fr_FR', :date => :pattern, :time => :pattern, :skeleton => 'MMMy')
88
-
89
- it 'check format' do
90
- expect(f4.format(t0)).to eq("nov. 2008")
91
- expect(f4.format(t1)).to eq("oct. 2008")
92
- end
93
-
94
- it 'check date_format' do
95
- expect(f4.date_format(true)).to eq("MMM y")
96
- end
97
- end
98
-
99
- context 'hour cycle' do
100
- # en_AU normally is 12 hours, fr_FR is normally 23 hours
101
- ['en_AU', 'fr_FR', 'zh_CN'].each do |locale_name|
102
- context "with locale #{locale_name}" do
103
- it 'works with hour_cycle: h11' do
104
- t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
105
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h11')
106
- expect(str).to match(/0:05/i)
107
- expect(str).to match(/(pm|下午)/i)
108
- end
109
-
110
- it 'works with hour_cycle: h12' do
111
- t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
112
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h12')
113
- expect(str).to match(/12:05/i)
114
- expect(str).to match(/(pm|下午)/i)
115
- end
116
-
117
- it 'works with hour_cycle: h23' do
118
- t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
119
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h23')
120
- expect(str).to match(/0:05/i)
121
- expect(str).to_not match(/(am|pm)/i)
122
- end
123
-
124
- it 'works with hour_cycle: h24' do
125
- t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
126
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale_name, zone: 'UTC', hour_cycle: 'h24')
127
- expect(str).to match(/24:05/i)
128
- expect(str).to_not match(/(am|pm)/i)
129
- end
130
-
131
- it 'does not include am/pm if time is not requested' do
132
- t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
133
- str = TimeFormatting.format(t, time: :none, date: :short, locale: locale_name, zone: 'UTC', hour_cycle: 'h12')
134
- expect(str).to_not match(/(am|pm|下午|上午)/i)
135
- end
136
-
137
- context '@hours keyword' do
138
- before(:each) do
139
- skip("Only works on ICU >= 67") if Lib.version.to_a[0] < 67
140
- end
141
-
142
- it 'works with @hours=h11 keyword' do
143
- t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
144
- locale = Locale.new(locale_name).with_keyword('hours', 'h11').to_s
145
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
146
- expect(str).to match(/0:05/i)
147
- expect(str).to match(/(pm|下午)/i)
148
- end
149
- it 'works with @hours=h12 keyword' do
150
- t = Time.new(2021, 04, 01, 12, 05, 0, "+00:00")
151
- locale = Locale.new(locale_name).with_keyword('hours', 'h12').to_s
152
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
153
- expect(str).to match(/12:05/i)
154
- expect(str).to match(/(pm|下午)/i)
155
- end
156
-
157
- it 'works with @hours=h23 keyword' do
158
- t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
159
- locale = Locale.new(locale_name).with_keyword('hours', 'h23').to_s
160
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
161
- expect(str).to match(/0:05/i)
162
- expect(str).to_not match(/(am|pm)/i)
163
- end
164
-
165
- it 'works with @hours=h24 keyword' do
166
- t = Time.new(2021, 04, 01, 00, 05, 0, "+00:00")
167
- locale = Locale.new(locale_name).with_keyword('hours', 'h24').to_s
168
- str = TimeFormatting.format(t, time: :short, date: :none, locale: locale, zone: 'UTC', hour_cycle: :locale)
169
- expect(str).to match(/24:05/i)
170
- expect(str).to_not match(/(am|pm)/i)
171
- end
172
- end
173
- end
174
- end
175
-
176
- it 'for lang=fi hour_cycle=h12' do
177
- t = Time.new(2021, 04, 01, 13, 05, 0, "+00:00")
178
- str = TimeFormatting.format(t, locale: 'fi', zone: 'America/Los_Angeles', date: :long, time: :short, hour_cycle: 'h12')
179
- expect(str).to match(/\sklo\s/)
180
- end
181
-
182
- it 'works with defaults on a h12 locale' do
183
- t = Time.new(2021, 04, 01, 13, 05, 0, "+00:00")
184
- str = TimeFormatting.format(t, time: :short, date: :none, locale: 'en_AU', zone: 'UTC', hour_cycle: :locale)
185
- expect(str).to match(/1:05/i)
186
- expect(str).to match(/pm/i)
187
- end
188
-
189
- it 'works with defaults on a h23 locale' do
190
- t = Time.new(2021, 04, 01, 0, 05, 0, "+00:00")
191
- str = TimeFormatting.format(t, time: :short, date: :none, locale: 'fr_FR', zone: 'UTC', hour_cycle: :locale)
192
- expect(str).to match(/0:05/i)
193
- expect(str).to_not match(/(am|pm)/i)
194
- end
195
- end
196
- end
197
- end
198
- end
@@ -1,36 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module ICU
4
- describe Transliteration::Transliterator do
5
- def transliterator_for(*args)
6
- Transliteration::Transliterator.new(*args)
7
- end
8
-
9
- [
10
- ["Any-Hex", "abcde", "\\u0061\\u0062\\u0063\\u0064\\u0065"],
11
- ["Lower", "ABC", "abc"],
12
- ["Han-Latin", "雙屬性集合之空間分群演算法-應用於地理資料", "shuāng shǔ xìng jí hé zhī kōng jiān fēn qún yǎn suàn fǎ-yīng yòng yú de lǐ zī liào"],
13
- ["Devanagari-Latin", "दौलत", "daulata"]
14
- ].each do |id, input, output|
15
- it "should transliterate #{id}" do
16
- tl = transliterator_for(id)
17
- expect(tl.transliterate(input)).to eq(output)
18
- end
19
-
20
- end
21
- end # Transliterator
22
-
23
- describe Transliteration do
24
- it "should provide a list of available ids" do
25
- ids = ICU::Transliteration.available_ids
26
-
27
- expect(ids).to be_an(Array)
28
- expect(ids).to_not be_empty
29
- end
30
-
31
- it "should transliterate custom rules" do
32
- expect(ICU::Transliteration.translit("NFD; [:Nonspacing Mark:] Remove; NFC", "âêîôû")).to eq("aeiou")
33
- end
34
-
35
- end # Transliteration
36
- end # ICU
data/spec/uchar_spec.rb DELETED
@@ -1,34 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module ICU
4
- describe UCharPointer do
5
- it 'allocates enough memory for 16-bit characters' do
6
- expect(UCharPointer.new(5).size).to eq(10)
7
- end
8
-
9
- it 'builds a buffer from a string' do
10
- ptr = UCharPointer.from_string('abc')
11
- expect(ptr).to be_a UCharPointer
12
- expect(ptr.size).to eq(6)
13
- expect(ptr.read_array_of_uint16(3)).to eq([0x61, 0x62, 0x63])
14
- end
15
-
16
- it 'takes an optional capacity' do
17
- ptr = UCharPointer.from_string('abc', 5)
18
- expect(ptr.size).to eq(10)
19
- end
20
-
21
- describe 'converting to string' do
22
- let(:ptr) { UCharPointer.new(3).write_array_of_uint16 [0x78, 0x0, 0x79] }
23
-
24
- it 'returns the the entire buffer by default' do
25
- expect(ptr.string).to eq("x\0y")
26
- end
27
-
28
- it 'returns strings of the specified length' do
29
- expect(ptr.string(0)).to eq("")
30
- expect(ptr.string(2)).to eq("x\0")
31
- end
32
- end
33
- end
34
- end
data/test.c DELETED
@@ -1,56 +0,0 @@
1
- #include <unicode/unorm.h>
2
- #include <unicode/ustdio.h>
3
- #include <stdio.h>
4
- #include <stdarg.h>
5
- #include <iconv.h>
6
- #include <string.h>
7
- #include <stdlib.h>
8
-
9
- void print_uchars(UChar *str) {
10
- UFILE *out = u_finit(stdout, NULL, NULL);
11
- u_fprintf(out, "uchars: %S\n", str);
12
- u_fclose(out);
13
- }
14
-
15
- void print_error(UErrorCode status) {
16
- printf("err: %s (%d)\n", u_errorName(status), status);
17
- }
18
-
19
- int main (int argc, char const *argv[])
20
- {
21
-
22
- UTransliterator* trans = NULL;
23
- UErrorCode status = U_ZERO_ERROR;
24
-
25
- trans = utrans_open("Any-Hex", UTRANS_FORWARD, NULL, 0, NULL, &status);
26
- if(U_FAILURE(status)) {
27
- print_error(status);
28
- exit(1);
29
- }
30
-
31
- UChar from[256];
32
- UChar buf[6];
33
-
34
- int32_t text_length, limit;
35
-
36
- u_uastrcpy(from, "abcde");
37
- u_strcpy(buf, from);
38
-
39
- limit = text_length = u_strlen(buf);
40
- printf("limit: %d\n", limit);
41
- printf("text_length: %d\n", limit);
42
-
43
- utrans_transUChars(trans, buf, &text_length, 256, 0, &limit, &status);
44
-
45
- printf("uchar ptr length after: %d\n", u_strlen(buf));
46
- printf("text_length after: %d\n", text_length);
47
-
48
- if(U_FAILURE(status)) {
49
- print_error(status);
50
- exit(1);
51
- }
52
-
53
- print_uchars(buf);
54
-
55
- return 0;
56
- }