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.
- checksums.yaml +4 -4
- data/Gemfile +10 -0
- data/LICENSE +1 -1
- data/README.md +21 -51
- data/Rakefile +4 -5
- data/ffi-icu.gemspec +34 -25
- data/lib/ffi-icu/break_iterator.rb +19 -18
- data/lib/ffi-icu/chardet.rb +12 -13
- data/lib/ffi-icu/collation.rb +62 -59
- data/lib/ffi-icu/duration_formatting.rb +293 -267
- data/lib/ffi-icu/lib/util.rb +10 -10
- data/lib/ffi-icu/lib.rb +273 -202
- data/lib/ffi-icu/locale.rb +14 -10
- data/lib/ffi-icu/normalization.rb +7 -7
- data/lib/ffi-icu/normalizer.rb +14 -8
- data/lib/ffi-icu/number_formatting.rb +41 -27
- data/lib/ffi-icu/time_formatting.rb +116 -93
- data/lib/ffi-icu/transliteration.rb +19 -19
- data/lib/ffi-icu/uchar.rb +14 -17
- data/lib/ffi-icu/version.rb +3 -1
- data/lib/ffi-icu.rb +16 -17
- metadata +35 -71
- data/.document +0 -5
- data/.gitignore +0 -23
- data/.rspec +0 -2
- data/.travis.yml +0 -28
- data/benchmark/detect.rb +0 -14
- data/benchmark/shared.rb +0 -17
- data/build_icu.sh +0 -53
- data/lib/ffi-icu/core_ext/string.rb +0 -9
- data/spec/break_iterator_spec.rb +0 -77
- data/spec/chardet_spec.rb +0 -42
- data/spec/collation_spec.rb +0 -84
- data/spec/duration_formatting_spec.rb +0 -143
- data/spec/lib/version_info_spec.rb +0 -20
- data/spec/lib_spec.rb +0 -63
- data/spec/locale_spec.rb +0 -280
- data/spec/normalization_spec.rb +0 -22
- data/spec/normalizer_spec.rb +0 -57
- data/spec/number_formatting_spec.rb +0 -79
- data/spec/spec_helper.rb +0 -13
- data/spec/time_spec.rb +0 -198
- data/spec/transliteration_spec.rb +0 -36
- data/spec/uchar_spec.rb +0 -34
- data/test.c +0 -56
data/spec/collation_spec.rb
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
module ICU
|
|
4
|
-
module Collation
|
|
5
|
-
describe "Collation" do
|
|
6
|
-
it "should collate an array of strings" do
|
|
7
|
-
expect(Collation.collate("nb", %w[æ å ø])).to eq(%w[æ ø å])
|
|
8
|
-
end
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
describe Collator do
|
|
12
|
-
let(:collator) { Collator.new("nb") }
|
|
13
|
-
|
|
14
|
-
it "should collate an array of strings" do
|
|
15
|
-
expect(collator.collate(%w[å ø æ])).to eq(%w[æ ø å])
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "raises an error if argument does not respond to :sort" do
|
|
19
|
-
expect { collator.collate(1) }.to raise_error(ArgumentError)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it "should return available locales" do
|
|
23
|
-
locales = ICU::Collation.available_locales
|
|
24
|
-
expect(locales).to be_an(Array)
|
|
25
|
-
expect(locales).to_not be_empty
|
|
26
|
-
expect(locales).to include("nb")
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "should return the locale of the collator" do
|
|
30
|
-
expect(collator.locale).to eq('nb')
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "should compare two strings" do
|
|
34
|
-
expect(collator.compare("blåbærsyltetøy", "blah")).to eq(1)
|
|
35
|
-
expect(collator.compare("blah", "blah")).to eq(0)
|
|
36
|
-
expect(collator.compare("ba", "bl")).to eq(-1)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "should know if a string is greater than another" do
|
|
40
|
-
expect(collator).to be_greater("z", "a")
|
|
41
|
-
expect(collator).to_not be_greater("a", "z")
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should know if a string is greater or equal to another" do
|
|
45
|
-
expect(collator).to be_greater_or_equal("z", "a")
|
|
46
|
-
expect(collator).to be_greater_or_equal("z", "z")
|
|
47
|
-
expect(collator).to_not be_greater_or_equal("a", "z")
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "should know if a string is equal to another" do
|
|
51
|
-
expect(collator).to be_equal("a", "a")
|
|
52
|
-
expect(collator).to_not be_equal("a", "b")
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
it "should return rules" do
|
|
56
|
-
expect(collator.rules).to_not be_empty
|
|
57
|
-
# ö sorts before Ö
|
|
58
|
-
expect(collator.rules).to include('ö<<<Ö')
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "returns usable collation keys" do
|
|
62
|
-
collator.collation_key("abc").should be < collator.collation_key("xyz")
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
context "attributes" do
|
|
66
|
-
it "can set and get normalization_mode" do
|
|
67
|
-
collator.normalization_mode = true
|
|
68
|
-
collator.normalization_mode.should be true
|
|
69
|
-
|
|
70
|
-
collator[:normalization_mode].should be true
|
|
71
|
-
collator[:normalization_mode] = false
|
|
72
|
-
collator.normalization_mode.should be false
|
|
73
|
-
|
|
74
|
-
collator.case_first.should be false
|
|
75
|
-
collator.case_first = :lower_first
|
|
76
|
-
collator.case_first.should == :lower_first
|
|
77
|
-
|
|
78
|
-
collator.strength = :tertiary
|
|
79
|
-
collator.strength.should == :tertiary
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end # Collate
|
|
84
|
-
end # ICU
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
module ICU
|
|
2
|
-
module DurationFormatting
|
|
3
|
-
describe 'DurationFormatting::format' do
|
|
4
|
-
before(:each) do
|
|
5
|
-
skip("Only works on ICU >= 67") if Lib.version.to_a[0] < 67
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
it 'produces hours, minutes, and seconds in order' do
|
|
9
|
-
result = DurationFormatting.format({hours: 1, minutes: 2, seconds: 3}, locale: 'C', style: :long)
|
|
10
|
-
expect(result).to match(/1.*hour.*2.*minute.*3.*second/i)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it 'rounds down fractional seconds < 0.5' do
|
|
14
|
-
result = DurationFormatting.format({seconds: 5.4}, locale: 'C', style: :long)
|
|
15
|
-
expect(result).to match(/5.*second/i)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it 'rounds up fractional seconds > 0.5' do
|
|
19
|
-
result = DurationFormatting.format({seconds: 5.6}, locale: 'C', style: :long)
|
|
20
|
-
expect(result).to match(/6.*second/i)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'trims off leading zero values' do
|
|
24
|
-
result = DurationFormatting.format({hours: 0, minutes: 1, seconds: 30}, locale: 'C', style: :long)
|
|
25
|
-
expect(result).to match(/1.*minute.*30.*second/i)
|
|
26
|
-
expect(result).to_not match(/hour/i)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it 'trims off leading missing values' do
|
|
30
|
-
result = DurationFormatting.format({minutes: 1, seconds: 30}, locale: 'C', style: :long)
|
|
31
|
-
expect(result).to match(/1.*minute.*30.*second/i)
|
|
32
|
-
expect(result).to_not match(/hour/i)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it 'trims off non-leading zero values' do
|
|
36
|
-
result = DurationFormatting.format({hours: 1, minutes: 0, seconds: 10}, locale: 'C', style: :long)
|
|
37
|
-
expect(result).to match(/1.*hour.*10.*second/i)
|
|
38
|
-
expect(result).to_not match(/minute/i)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'trims off non-leading missing values' do
|
|
42
|
-
result = DurationFormatting.format({hours: 1, seconds: 10}, locale: 'C', style: :long)
|
|
43
|
-
expect(result).to match(/1.*hour.*10.*second/i)
|
|
44
|
-
expect(result).to_not match(/minute/i)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it 'uses comma-based number formatting as appropriate for locale' do
|
|
48
|
-
result = DurationFormatting.format({seconds: 90123}, locale: 'en-AU', style: :long)
|
|
49
|
-
expect(result).to match(/90,123.*second/i)
|
|
50
|
-
expect(result).to_not match(/hour/i)
|
|
51
|
-
expect(result).to_not match(/minute/i)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it 'localizes unit names' do
|
|
55
|
-
result = DurationFormatting.format({hours: 1, minutes: 2, seconds: 3}, locale: 'el', style: :long)
|
|
56
|
-
expect(result).to match(/1.*ώρα.*2.*λεπτά.*3.*δευτερόλεπτα/i)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it 'can format long' do
|
|
60
|
-
result = DurationFormatting.format({hours: 1, minutes: 2, seconds: 3}, locale: 'en-AU', style: :long)
|
|
61
|
-
expect(result).to match(/hour.*minute.*second/i)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
it 'can format short' do
|
|
65
|
-
result = DurationFormatting.format({hours: 1, minutes: 2, seconds: 3}, locale: 'en-AU', style: :short)
|
|
66
|
-
expect(result).to match(/hr.*min.*sec/i)
|
|
67
|
-
expect(result).to_not match(/hour/i)
|
|
68
|
-
expect(result).to_not match(/minute/i)
|
|
69
|
-
expect(result).to_not match(/second/i)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it 'can format narrow' do
|
|
73
|
-
result = DurationFormatting.format({hours: 1, minutes: 2, seconds: 3}, locale: 'en-AU', style: :narrow)
|
|
74
|
-
expect(result).to match(/h.*min.*s/i)
|
|
75
|
-
expect(result).to_not match(/hr/i)
|
|
76
|
-
expect(result).to_not match(/sec/i)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it 'can format digital' do
|
|
80
|
-
result = DurationFormatting.format({hours: 1, minutes: 2, seconds: 3}, locale: 'en-AU', style: :digital)
|
|
81
|
-
expect(result).to eql('1:02:03')
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it 'can format the full sequence of time units in order' do
|
|
85
|
-
duration = {
|
|
86
|
-
years: 1,
|
|
87
|
-
months: 2,
|
|
88
|
-
weeks: 3,
|
|
89
|
-
days: 4,
|
|
90
|
-
hours: 5,
|
|
91
|
-
minutes: 6,
|
|
92
|
-
seconds: 7,
|
|
93
|
-
milliseconds: 8,
|
|
94
|
-
microseconds: 9,
|
|
95
|
-
nanoseconds: 10,
|
|
96
|
-
}
|
|
97
|
-
result = DurationFormatting.format(duration, locale: 'en-AU', style: :short)
|
|
98
|
-
expect(result).to match(/1.yr.*2.*mths.*3.*wks.*4.*days.*5.*hrs.*6.*mins.*7.*secs.*8.*ms.*9.*μs.*10.*ns/)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it 'joins ms, us, ns values to seconds in digital format' do
|
|
102
|
-
duration = {minutes: 10, seconds: 5, milliseconds: 325, microseconds: 53, nanoseconds: 236}
|
|
103
|
-
result = DurationFormatting.format(duration, locale: 'en-AU', style: :digital)
|
|
104
|
-
expect(result).to eql('10:05.325053236')
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it 'includes trailing zeros as appropriate for the last unit in digital format' do
|
|
108
|
-
duration = {minutes: 10, seconds: 5, milliseconds: 325, microseconds: 400}
|
|
109
|
-
result = DurationFormatting.format(duration, locale: 'en-AU', style: :digital)
|
|
110
|
-
expect(result).to eql('10:05.325400')
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
it 'joins h:mm:ss and other units in digital format' do
|
|
114
|
-
duration = {days: 8, hours: 23, minutes: 10, seconds: 9}
|
|
115
|
-
result = DurationFormatting.format(duration, locale: 'en-AU', style: :digital)
|
|
116
|
-
expect(result).to match(/8.*d.*23:10:09/ )
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it 'ignores all decimal parts except the last, if it is seconds' do
|
|
120
|
-
duration = {hours: 7.3, minutes: 9.7, seconds: 8.93}
|
|
121
|
-
result = DurationFormatting.format(duration, locale: 'en-AU', style: :short)
|
|
122
|
-
expect(result).to match(/7[^0-9]*hrs.*9[^0-9]*min.*8\.93[^0-9]*secs/)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it 'ignores all decimal parts except the last, if it is milliseconds' do
|
|
126
|
-
duration = {hours: 7.3, minutes: 9.7, seconds: 8.93, milliseconds: 632.2}
|
|
127
|
-
result = DurationFormatting.format(duration, locale: 'en-AU', style: :short)
|
|
128
|
-
expect(result).to match(/7[^0-9]*hrs.*9[^0-9]*min.*8[^0-9]*secs.*632\.2[^0-9]*ms/)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
it 'ignores all decimal parts including the last, if it is > seconds' do
|
|
132
|
-
duration = {hours: 7.3, minutes: 9.7}
|
|
133
|
-
result = DurationFormatting.format(duration, locale: 'en-AU', style: :short)
|
|
134
|
-
expect(result).to match(/7[^0-9]*hrs.*9[^0-9]*min/)
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it 'raises on durations with any negative component' do
|
|
138
|
-
duration = {hours: 7.3, minutes: -9.7}
|
|
139
|
-
expect { DurationFormatting.format(duration, locale: 'en-AU') }.to raise_error(ArgumentError)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
module ICU
|
|
4
|
-
module Lib
|
|
5
|
-
describe VersionInfo do
|
|
6
|
-
describe '.to_a' do
|
|
7
|
-
subject { described_class.new.to_a }
|
|
8
|
-
|
|
9
|
-
it { is_expected.to be_an(Array) }
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
describe '.to_s' do
|
|
13
|
-
subject { described_class.new.to_s }
|
|
14
|
-
|
|
15
|
-
it { is_expected.to be_a(String) }
|
|
16
|
-
it { is_expected.to match(/^[0-9.]+$/) }
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
data/spec/lib_spec.rb
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
module ICU
|
|
4
|
-
describe Lib do
|
|
5
|
-
describe 'error checking' do
|
|
6
|
-
let(:return_value) { double }
|
|
7
|
-
|
|
8
|
-
context 'upon success' do
|
|
9
|
-
it 'returns the block result' do
|
|
10
|
-
expect(Lib.check_error { |status| return_value }).to eq(return_value)
|
|
11
|
-
expect(Lib.check_error { |status| status.write_int(0); return_value }).to eq(return_value)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
context 'upon failure' do
|
|
16
|
-
it 'raises an error' do
|
|
17
|
-
expect { Lib.check_error { |status| status.write_int(1) } }.to raise_error ICU::Error, /U_.*_ERROR/
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
context 'upon warning' do
|
|
22
|
-
before(:each) { @verbose = $VERBOSE }
|
|
23
|
-
after(:each) { $VERBOSE = @verbose }
|
|
24
|
-
|
|
25
|
-
context 'when warnings are enabled' do
|
|
26
|
-
before(:each) { $VERBOSE = true }
|
|
27
|
-
|
|
28
|
-
it 'prints to STDERR and returns the block result' do
|
|
29
|
-
expect($stderr).to receive(:puts) { |message| expect(message).to match /U_.*_WARNING/ }
|
|
30
|
-
error_check = Lib.check_error { |status| status.write_int(-127); return_value }
|
|
31
|
-
expect(error_check).to eq(return_value)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context 'when warnings are disabled' do
|
|
36
|
-
before(:each) { $VERBOSE = false }
|
|
37
|
-
|
|
38
|
-
it 'returns the block result' do
|
|
39
|
-
expect($stderr).to_not receive(:puts)
|
|
40
|
-
error_check = Lib.check_error { |status| status.write_int(-127); return_value }
|
|
41
|
-
expect(error_check).to eq(return_value)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
if Gem::Version.new('4.2') <= Gem::Version.new(Lib.version)
|
|
48
|
-
describe 'CLDR version' do
|
|
49
|
-
subject { Lib.cldr_version }
|
|
50
|
-
|
|
51
|
-
it { should be_a Lib::VersionInfo }
|
|
52
|
-
it('is populated') { expect(subject.to_a).to_not eq([0,0,0,0]) }
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
describe 'ICU version' do
|
|
57
|
-
subject { Lib.version }
|
|
58
|
-
|
|
59
|
-
it { is_expected.to be_a Lib::VersionInfo }
|
|
60
|
-
it('is populated') { expect(subject.to_a).to_not eq([0,0,0,0]) }
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
data/spec/locale_spec.rb
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
module ICU
|
|
4
|
-
describe Locale do
|
|
5
|
-
describe 'the available locales' do
|
|
6
|
-
subject { Locale.available }
|
|
7
|
-
|
|
8
|
-
it { is_expected.to be_an Array }
|
|
9
|
-
it { is_expected.to_not be_empty }
|
|
10
|
-
|
|
11
|
-
it 'should be an array of available Locales' do
|
|
12
|
-
expect(subject.first).to be_a(Locale)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
describe 'the available ISO 639 country codes' do
|
|
17
|
-
subject { Locale.iso_countries }
|
|
18
|
-
|
|
19
|
-
it { is_expected.to be_an Array }
|
|
20
|
-
it { is_expected.to_not be_empty }
|
|
21
|
-
|
|
22
|
-
it 'should be an array of Strings' do
|
|
23
|
-
expect(subject.first).to be_a(String)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
describe 'the available ISO 639 language codes' do
|
|
28
|
-
subject { Locale.iso_languages }
|
|
29
|
-
|
|
30
|
-
it { is_expected.to be_an Array }
|
|
31
|
-
it { is_expected.to_not be_empty }
|
|
32
|
-
|
|
33
|
-
it 'should be an array of Strings' do
|
|
34
|
-
expect(subject.first).to be_a(String)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
describe 'the default' do
|
|
39
|
-
subject { Locale.default }
|
|
40
|
-
|
|
41
|
-
let(:locale) do
|
|
42
|
-
locales = Locale.available
|
|
43
|
-
locales.delete(Locale.default)
|
|
44
|
-
locales.respond_to?(:sample) ? locales.sample : locales.choice
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it { is_expected.to be_a Locale }
|
|
48
|
-
|
|
49
|
-
it 'can be assigned using Locale' do
|
|
50
|
-
expect(Locale.default = locale).to eq(locale)
|
|
51
|
-
expect(Locale.default).to eq(locale)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it 'can be assigned using string' do
|
|
55
|
-
string = locale.to_s
|
|
56
|
-
|
|
57
|
-
expect(Locale.default = string).to eq(string)
|
|
58
|
-
expect(Locale.default).to eq(Locale.new(string))
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it 'can be assigned using symbol' do
|
|
62
|
-
symbol = locale.to_s.to_sym
|
|
63
|
-
|
|
64
|
-
expect(Locale.default = symbol).to eq(symbol)
|
|
65
|
-
expect(Locale.default).to eq(Locale.new(symbol))
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
if Gem::Version.new('4.2') <= Gem::Version.new(Lib.version)
|
|
70
|
-
describe 'BCP 47 language tags' do
|
|
71
|
-
it 'converts a language tag to a locale' do
|
|
72
|
-
expect(Locale.for_language_tag('en-us')).to eq(Locale.new('en_US'))
|
|
73
|
-
expect(Locale.for_language_tag('nan-Hant-tw')).to eq(Locale.new('nan_Hant_TW'))
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it 'returns a language tag for a locale' do
|
|
77
|
-
if Gem::Version.new('4.4') <= Gem::Version.new(Lib.version)
|
|
78
|
-
expect(Locale.new('en_US').to_language_tag).to eq('en-US')
|
|
79
|
-
expect(Locale.new('zh_TW').to_language_tag).to eq('zh-TW')
|
|
80
|
-
# Support for this "magic" transform was dropped with https://unicode-org.atlassian.net/browse/ICU-20187, so don't test it
|
|
81
|
-
if Gem::Version.new(Lib.version) < Gem::Version.new('64')
|
|
82
|
-
expect(Locale.new('zh_Hans_CH_PINYIN').to_language_tag).to eq('zh-Hans-CH-u-co-pinyin')
|
|
83
|
-
else
|
|
84
|
-
expect(Locale.new('zh_Hans_CH@collation=pinyin').to_language_tag).to eq('zh-Hans-CH-u-co-pinyin')
|
|
85
|
-
end
|
|
86
|
-
else
|
|
87
|
-
expect(Locale.new('en_US').to_language_tag).to eq('en-us')
|
|
88
|
-
expect(Locale.new('zh_TW').to_language_tag).to eq('zh-tw')
|
|
89
|
-
expect(Locale.new('zh_Hans_CH_PINYIN').to_language_tag).to eq('zh-hans-ch-u-co-pinyin')
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
describe 'Win32 locale IDs' do
|
|
96
|
-
it 'converts an LCID to a locale' do
|
|
97
|
-
expect(Locale.for_lcid(1033)).to eq(Locale.new('en_US'))
|
|
98
|
-
expect(Locale.for_lcid(1036)).to eq(Locale.new('fr_FR'))
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it 'returns an LCID for a locale' do
|
|
102
|
-
expect(Locale.new('en_US').lcid).to eq(1033)
|
|
103
|
-
expect(Locale.new('es_US').lcid).to eq(21514)
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
describe 'display' do
|
|
108
|
-
let(:locale_ids) { Locale.available.map(&:id) }
|
|
109
|
-
|
|
110
|
-
context 'in a specific locale' do
|
|
111
|
-
it 'returns the country' do
|
|
112
|
-
expect(Locale.new('de_DE').display_country('en')).to eq('Germany')
|
|
113
|
-
expect(Locale.new('en_US').display_country('fr')).to eq('États-Unis')
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
it 'returns the language' do
|
|
117
|
-
expect(Locale.new('fr_FR').display_language('de')).to eq('Französisch')
|
|
118
|
-
expect(Locale.new('zh_CH').display_language('en')).to eq('Chinese')
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
it 'returns the name' do
|
|
122
|
-
expect(Locale.new('en_US').display_name('de')).to eq('Englisch (Vereinigte Staaten)')
|
|
123
|
-
expect(Locale.new('zh_CH').display_name('fr')).to eq('chinois (Suisse)')
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it 'returns the name using display context' do
|
|
127
|
-
expect(Locale.new('en_US').display_name_with_context('en_HK', [:length_full])).to eq('English (Hong Kong SAR China)')
|
|
128
|
-
expect(Locale.new('en_US').display_name_with_context('en_HK', [:length_short])).to eq('English (Hong Kong)')
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
it 'returns the script' do
|
|
132
|
-
expect(Locale.new('ja_Hira_JP').display_script('en')).to eq('Hiragana')
|
|
133
|
-
expect(Locale.new('ja_Hira_JP').display_script('ru')).to eq('хирагана')
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it 'returns the variant' do
|
|
137
|
-
expect(Locale.new('be_BY_TARASK').display_variant('de')).to eq('Taraskievica-Orthographie')
|
|
138
|
-
expect(Locale.new('zh_CH_POSIX').display_variant('en')).to eq('Computer')
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# If memory set for 'read_uchar_buffer' is set too low it will throw an out
|
|
142
|
-
# of bounds memory error, which results in a Segmentation fault error.
|
|
143
|
-
it 'insures memory sizes is set correctly' do
|
|
144
|
-
# Currently, testing the longest known locales. May need to be update in the future.
|
|
145
|
-
expect(Locale.new('en_VI').display_country('ccp')).to_not be_nil
|
|
146
|
-
expect(Locale.new('yue_Hant').display_language('ccp')).to_not be_nil
|
|
147
|
-
expect(Locale.new('en_VI').display_name('ccp')).to_not be_nil
|
|
148
|
-
expect(Locale.new('ccp').display_name_with_context('en_VI')).to_not be_nil
|
|
149
|
-
expect(Locale.new('yue_Hant').display_script('ccp')).to_not be_nil
|
|
150
|
-
expect(Locale.new('en_US_POSIX').display_variant('sl')).to_not be_nil
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
context 'in the default locale' do
|
|
155
|
-
let(:locale) { Locale.new('de_DE') }
|
|
156
|
-
|
|
157
|
-
it 'returns the country' do
|
|
158
|
-
expect(locale.display_country).to eq(locale.display_country(Locale.default))
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
it 'returns the language' do
|
|
162
|
-
expect(locale.display_language).to eq(locale.display_language(Locale.default))
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
it 'returns the name' do
|
|
166
|
-
expect(locale.display_name).to eq(locale.display_name(Locale.default))
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
it 'returns the script' do
|
|
170
|
-
expect(locale.display_script).to eq(locale.display_script(Locale.default))
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
it 'returns the variant' do
|
|
174
|
-
expect(locale.display_variant).to eq(locale.display_variant(Locale.default))
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
describe 'formatting' do
|
|
180
|
-
let(:locale) { Locale.new('de-de.utf8@collation = phonebook') }
|
|
181
|
-
|
|
182
|
-
it('is formatted') { expect(locale.name).to eq('de_DE.utf8@collation=phonebook') }
|
|
183
|
-
it('is formatted without keywords') { expect(locale.base_name).to eq('de_DE.utf8') }
|
|
184
|
-
it('is formatted for ICU') { expect(locale.canonical).to eq('de_DE@collation=phonebook') }
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
it 'truncates a properly formatted locale, returning the "parent"' do
|
|
188
|
-
expect(Locale.new('es-mx').parent).to eq('')
|
|
189
|
-
expect(Locale.new('es_MX').parent).to eq('es')
|
|
190
|
-
expect(Locale.new('zh_Hans_CH_PINYIN').parent).to eq('zh_Hans_CH')
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
describe 'ISO codes' do
|
|
194
|
-
it 'returns the ISO 3166 alpha-3 country code' do
|
|
195
|
-
expect(Locale.new('en_US').iso_country).to eq('USA')
|
|
196
|
-
expect(Locale.new('zh_CN').iso_country).to eq('CHN')
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
it 'returns the ISO 639 three-letter language code' do
|
|
200
|
-
expect(Locale.new('en_US').iso_language).to eq('eng')
|
|
201
|
-
expect(Locale.new('zh_CN').iso_language).to eq('zho')
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
describe 'keywords' do
|
|
206
|
-
context 'when improperly formatted' do
|
|
207
|
-
let(:locale) { Locale.new('de_DE@euro') }
|
|
208
|
-
|
|
209
|
-
it 'raises an error' do
|
|
210
|
-
expect { locale.keywords }.to raise_error(ICU::Error)
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
context 'when properly formatted' do
|
|
215
|
-
let(:locale) { Locale.new('de_DE@currency=EUR') }
|
|
216
|
-
|
|
217
|
-
it 'returns the list of keywords' do
|
|
218
|
-
expect(locale.keywords).to eq(['currency'])
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
it 'can be read' do
|
|
223
|
-
expect(Locale.new('en_US@calendar=chinese').keyword('calendar')).to eq('chinese')
|
|
224
|
-
expect(Locale.new('en_US@calendar=chinese').keyword(:calendar)).to eq('chinese')
|
|
225
|
-
expect(Locale.new('en_US@some=thing').keyword('missing')).to eq('')
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
it 'can be added' do
|
|
229
|
-
expect(Locale.new('de_DE').with_keyword('currency', 'EUR')).to eq(Locale.new('de_DE@currency=EUR'))
|
|
230
|
-
expect(Locale.new('de_DE').with_keyword(:currency, :EUR)).to eq(Locale.new('de_DE@currency=EUR'))
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
it 'can be added using hash' do
|
|
234
|
-
expect(Locale.new('fr').with_keywords(:a => :b, :c => :d)).to eq(Locale.new('fr@a=b;c=d'))
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
it 'can be removed' do
|
|
238
|
-
expect(Locale.new('en_US@some=thing').with_keyword(:some, nil)).to eq(Locale.new('en_US'))
|
|
239
|
-
expect(Locale.new('en_US@some=thing').with_keyword(:some, '')).to eq(Locale.new('en_US'))
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
describe 'orientation' do
|
|
244
|
-
it 'returns the character orientation' do
|
|
245
|
-
expect(Locale.new('ar').character_orientation).to eq(:rtl)
|
|
246
|
-
expect(Locale.new('en').character_orientation).to eq(:ltr)
|
|
247
|
-
expect(Locale.new('fa').character_orientation).to eq(:rtl)
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
it 'returns the line orientation' do
|
|
251
|
-
expect(Locale.new('ar').line_orientation).to eq(:ttb)
|
|
252
|
-
expect(Locale.new('en').line_orientation).to eq(:ttb)
|
|
253
|
-
expect(Locale.new('fa').line_orientation).to eq(:ttb)
|
|
254
|
-
end
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
describe 'subtags' do
|
|
258
|
-
let(:locale) { Locale.new('zh-hans-ch-pinyin') }
|
|
259
|
-
|
|
260
|
-
it('returns the country code') { expect(locale.country).to eq('CH') }
|
|
261
|
-
it('returns the language code') { expect(locale.language).to eq('zh') }
|
|
262
|
-
it('returns the script code') { expect(locale.script).to eq('Hans') }
|
|
263
|
-
it('returns the variant code') { expect(locale.variant).to eq('PINYIN') }
|
|
264
|
-
|
|
265
|
-
describe 'likely subtags according to UTS #35' do
|
|
266
|
-
it 'adds likely subtags' do
|
|
267
|
-
expect(Locale.new('en').with_likely_subtags).to eq(Locale.new('en_Latn_US'))
|
|
268
|
-
expect(Locale.new('sr').with_likely_subtags).to eq(Locale.new('sr_Cyrl_RS'))
|
|
269
|
-
expect(Locale.new('zh_TW').with_likely_subtags).to eq(Locale.new('zh_Hant_TW'))
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
it 'removes likely subtags' do
|
|
273
|
-
expect(Locale.new('en_US').with_minimized_subtags).to eq(Locale.new('en'))
|
|
274
|
-
expect(Locale.new('sr_RS').with_minimized_subtags).to eq(Locale.new('sr'))
|
|
275
|
-
expect(Locale.new('zh_Hant_TW').with_minimized_subtags).to eq(Locale.new('zh_TW'))
|
|
276
|
-
end
|
|
277
|
-
end
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
end
|
data/spec/normalization_spec.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
module ICU
|
|
4
|
-
module Normalization
|
|
5
|
-
# http://bugs.icu-project.org/trac/browser/icu/trunk/source/test/cintltst/cnormtst.c
|
|
6
|
-
|
|
7
|
-
describe "Normalization" do
|
|
8
|
-
|
|
9
|
-
it "should normalize a string - decomposed" do
|
|
10
|
-
expect(ICU::Normalization.normalize("Å", :nfd).unpack("U*")).to eq([65, 778])
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "should normalize a string - composed" do
|
|
14
|
-
expect(ICU::Normalization.normalize("Å", :nfc).unpack("U*")).to eq([197])
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# TODO: add more normalization tests
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
21
|
-
end # Normalization
|
|
22
|
-
end # ICU
|
data/spec/normalizer_spec.rb
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
|
-
|
|
3
|
-
module ICU
|
|
4
|
-
describe Normalizer do
|
|
5
|
-
describe 'NFD: nfc decompose' do
|
|
6
|
-
let(:normalizer) { ICU::Normalizer.new(nil, 'nfc', :decompose) }
|
|
7
|
-
|
|
8
|
-
it "should normalize a string" do
|
|
9
|
-
expect(normalizer.normalize("Å").unpack("U*")).to eq([65, 778])
|
|
10
|
-
expect(normalizer.normalize("ô").unpack("U*")).to eq([111, 770])
|
|
11
|
-
expect(normalizer.normalize("a").unpack("U*")).to eq([97])
|
|
12
|
-
expect(normalizer.normalize("中文").unpack("U*")).to eq([20013, 25991])
|
|
13
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([65, 776, 102, 102, 105, 110])
|
|
14
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([65, 776, 64259, 110])
|
|
15
|
-
expect(normalizer.normalize("Henry IV").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 73, 86])
|
|
16
|
-
expect(normalizer.normalize("Henry Ⅳ").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 8547])
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
describe 'NFC: nfc compose' do
|
|
21
|
-
let(:normalizer) { ICU::Normalizer.new(nil, 'nfc', :compose) }
|
|
22
|
-
|
|
23
|
-
it "should normalize a string" do
|
|
24
|
-
expect(normalizer.normalize("Å").unpack("U*")).to eq([197])
|
|
25
|
-
expect(normalizer.normalize("ô").unpack("U*")).to eq([244])
|
|
26
|
-
expect(normalizer.normalize("a").unpack("U*")).to eq([97])
|
|
27
|
-
expect(normalizer.normalize("中文").unpack("U*")).to eq([20013, 25991])
|
|
28
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([196, 102, 102, 105, 110])
|
|
29
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([196, 64259, 110])
|
|
30
|
-
expect(normalizer.normalize("Henry IV").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 73, 86])
|
|
31
|
-
expect(normalizer.normalize("Henry Ⅳ").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 8547])
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
describe 'NFKD: nfkc decompose' do
|
|
36
|
-
let(:normalizer) { ICU::Normalizer.new(nil, 'nfkc', :decompose) }
|
|
37
|
-
|
|
38
|
-
it "should normalize a string" do
|
|
39
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([65, 776, 102, 102, 105, 110])
|
|
40
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([65, 776, 102, 102, 105, 110])
|
|
41
|
-
expect(normalizer.normalize("Henry IV").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 73, 86])
|
|
42
|
-
expect(normalizer.normalize("Henry Ⅳ").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 73, 86])
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe 'NFKC: nfkc compose' do
|
|
47
|
-
let(:normalizer) { ICU::Normalizer.new(nil, 'nfkc', :compose) }
|
|
48
|
-
|
|
49
|
-
it "should normalize a string" do
|
|
50
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([196, 102, 102, 105, 110])
|
|
51
|
-
expect(normalizer.normalize("Äffin").unpack("U*")).to eq([196, 102, 102, 105, 110])
|
|
52
|
-
expect(normalizer.normalize("Henry IV").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 73, 86])
|
|
53
|
-
expect(normalizer.normalize("Henry Ⅳ").unpack("U*")).to eq([72, 101, 110, 114, 121, 32, 73, 86])
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end # Normalizer
|
|
57
|
-
end # ICU
|