ffi-icu 0.2.0 → 0.4.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 +5 -5
- data/.rspec +2 -0
- data/.travis.yml +16 -3
- data/README.md +20 -11
- data/ffi-icu.gemspec +2 -3
- data/lib/ffi-icu/lib.rb +16 -9
- data/lib/ffi-icu/number_formatting.rb +13 -4
- data/lib/ffi-icu/time_formatting.rb +46 -8
- data/lib/ffi-icu/version.rb +1 -1
- data/lib/ffi-icu.rb +0 -9
- data/spec/break_iterator_spec.rb +20 -19
- data/spec/chardet_spec.rb +10 -12
- data/spec/collation_spec.rb +19 -22
- data/spec/lib/version_info_spec.rb +11 -6
- data/spec/lib_spec.rb +11 -11
- data/spec/locale_spec.rb +97 -85
- data/spec/normalization_spec.rb +2 -4
- data/spec/normalizer_spec.rb +24 -26
- data/spec/number_formatting_spec.rb +33 -25
- data/spec/time_spec.rb +48 -38
- data/spec/transliteration_spec.rb +6 -7
- data/spec/uchar_spec.rb +8 -10
- metadata +12 -20
- data/spec/spec.opts +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 448bbb49f51d0f81ab1aba8425c9c814fa9bb2ca06317022f1bc703769d87838
|
4
|
+
data.tar.gz: 27331bf11c467dc52c4ddb4bfbee954d7b0682dbeb90e802482631640e0db0fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6d001728de2428460f163248ed9394680e9ca5509aa0644b9290de294993637ff982ec0fe7e87f40f3f1fba4a6b9dfe542147ed9a699588aae9aa80b5d01c59
|
7
|
+
data.tar.gz: 3c9fa41df884315d1d4a9e726b4d55c20d1d962c6e9abce260a9ab68a9ae12cb4ba0c7a8fb0f04628b9e9497c41594a5394a994f2b154aad4da1d177f4997abd
|
data/.rspec
ADDED
data/.travis.yml
CHANGED
@@ -1,7 +1,20 @@
|
|
1
|
+
language: ruby
|
2
|
+
os: linux
|
3
|
+
dist: focal
|
4
|
+
|
5
|
+
arch:
|
6
|
+
- amd64
|
7
|
+
- arm64
|
8
|
+
|
1
9
|
rvm:
|
2
|
-
- 2.
|
3
|
-
- 2.
|
4
|
-
-
|
10
|
+
- 2.6
|
11
|
+
- 2.7
|
12
|
+
- 3.0
|
5
13
|
- ruby-head
|
14
|
+
|
6
15
|
before_script:
|
7
16
|
- sudo apt-get install -y libicu-dev
|
17
|
+
|
18
|
+
jobs:
|
19
|
+
allow_failures:
|
20
|
+
- arch: arm64
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
ffi-icu
|
1
|
+
ffi-icu [](https://travis-ci.org/erickguan/ffi-icu)
|
2
2
|
=======
|
3
3
|
|
4
4
|
Simple FFI wrappers for ICU. Checkout the renovated [ICU gem](https://github.com/fantasticfears/icu4r) instead which supports various of encoding and distributed with packaged source. FFI-ICU needs some love with ICU gem's transcoding method.
|
@@ -16,7 +16,7 @@ Dependencies
|
|
16
16
|
ICU.
|
17
17
|
|
18
18
|
If you get messages that the library or functions are not found, you can
|
19
|
-
set some environment
|
19
|
+
set some environment variables to tell ffi-icu where to find it, e.g.:
|
20
20
|
|
21
21
|
$ export FFI_ICU_LIB="icui18n.so"
|
22
22
|
$ export FFI_ICU_VERSION_SUFFIX="_3_8"
|
@@ -47,7 +47,6 @@ or
|
|
47
47
|
Why not just use rchardet?
|
48
48
|
|
49
49
|
* speed
|
50
|
-
* 1.9 support
|
51
50
|
|
52
51
|
Locale Sensitive Collation
|
53
52
|
--------------------------
|
@@ -110,14 +109,24 @@ Examples:
|
|
110
109
|
f #=> "12.11.15 15:21"
|
111
110
|
|
112
111
|
# reusable formatting objects
|
113
|
-
|
114
|
-
|
112
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :zone => 'Europe/Prague', :date => :long, :time => :none)
|
113
|
+
formatter.format(Time.now) #=> "25. února 2015"
|
115
114
|
```
|
116
115
|
|
117
116
|
```ruby
|
118
117
|
# reusable formatting objects
|
119
|
-
|
120
|
-
|
118
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :zone => 'Europe/Prague', :date => :long, :time => :none)
|
119
|
+
formatter.parse("25. února 2015") #=> Wed Feb 25 00:00:00 +0100 2015
|
120
|
+
```
|
121
|
+
|
122
|
+
For skeleton formatting, visit the [Unicode date field symbol table](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table) page to help find the pattern characters to use.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :date => :pattern, :time => :pattern, :skeleton => 'MMMMY')
|
126
|
+
formatter.format(Time.now) #=> "únor 2015"
|
127
|
+
|
128
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :date => :pattern, :time => :pattern, :skeleton => 'Y')
|
129
|
+
formatter.format(Time.now) #=> "2015"
|
121
130
|
```
|
122
131
|
|
123
132
|
Tested on:
|
@@ -130,15 +139,15 @@ Platforms:
|
|
130
139
|
|
131
140
|
Rubies:
|
132
141
|
|
133
|
-
- 2.
|
134
|
-
- 2.
|
135
|
-
- 2.
|
142
|
+
- 2.5
|
143
|
+
- 2.6
|
144
|
+
- 2.7
|
136
145
|
- ruby-head
|
137
146
|
|
138
147
|
TODO:
|
139
148
|
=====
|
140
149
|
|
141
|
-
* Any other useful part of ICU?
|
150
|
+
* Any other useful part of ICU?
|
142
151
|
* Windows?!
|
143
152
|
|
144
153
|
Note on Patches/Pull Requests
|
data/ffi-icu.gemspec
CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.summary = %q{Simple Ruby FFI wrappers for things I need from ICU.}
|
22
22
|
|
23
23
|
s.add_runtime_dependency "ffi", "~> 1.0", ">= 1.0.9"
|
24
|
-
s.add_development_dependency 'rspec', '~>
|
25
|
-
s.add_development_dependency "rake", ["
|
24
|
+
s.add_development_dependency 'rspec', '~> 3.9'
|
25
|
+
s.add_development_dependency "rake", [">= 12.3.3"]
|
26
26
|
end
|
27
|
-
|
data/lib/ffi-icu/lib.rb
CHANGED
@@ -19,9 +19,7 @@ module ICU
|
|
19
19
|
'/usr/local/{lib64,lib}',
|
20
20
|
'/opt/local/{lib64,lib}',
|
21
21
|
'/usr/{lib64,lib}',
|
22
|
-
|
23
|
-
'/usr/lib/i386-linux-gnu', # for Debian Multiarch
|
24
|
-
]
|
22
|
+
] + Dir['/usr/lib/*-linux-gnu'] # for Debian Multiarch http://wiki.debian.org/Multiarch
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -39,7 +37,12 @@ module ICU
|
|
39
37
|
[find_lib("libicui18n.#{FFI::Platform::LIBSUFFIX}.??"),
|
40
38
|
find_lib("libicutu.#{FFI::Platform::LIBSUFFIX}.??")]
|
41
39
|
when :osx
|
42
|
-
|
40
|
+
# See https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11_0_1-release-notes (62986286)
|
41
|
+
if Gem::Version.new(`sw_vers -productVersion`) >= Gem::Version.new('11')
|
42
|
+
["libicucore.#{FFI::Platform::LIBSUFFIX}"]
|
43
|
+
else
|
44
|
+
[find_lib("libicucore.#{FFI::Platform::LIBSUFFIX}")]
|
45
|
+
end
|
43
46
|
when :linux
|
44
47
|
[find_lib("libicui18n.#{FFI::Platform::LIBSUFFIX}.??"),
|
45
48
|
find_lib("libicutu.#{FFI::Platform::LIBSUFFIX}.??")]
|
@@ -420,11 +423,12 @@ module ICU
|
|
420
423
|
attach_function :unum_set_attribute, "unum_setAttribute#{suffix}", [:pointer, :number_format_attribute, :int32_t], :void
|
421
424
|
# date
|
422
425
|
enum :date_format_style, [
|
423
|
-
:
|
424
|
-
:
|
425
|
-
:
|
426
|
-
:
|
427
|
-
:
|
426
|
+
:pattern, -2,
|
427
|
+
:none, -1,
|
428
|
+
:full, 0,
|
429
|
+
:long, 1,
|
430
|
+
:medium, 2,
|
431
|
+
:short, 3,
|
428
432
|
]
|
429
433
|
attach_function :udat_open, "udat_open#{suffix}", [:date_format_style, :date_format_style, :string, :pointer, :int32_t, :pointer, :int32_t, :pointer ], :pointer
|
430
434
|
attach_function :udat_close, "unum_close#{suffix}", [:pointer], :void
|
@@ -432,6 +436,9 @@ module ICU
|
|
432
436
|
attach_function :udat_parse, "udat_parse#{suffix}", [:pointer, :pointer, :int32_t, :pointer, :pointer], :double
|
433
437
|
attach_function :udat_toPattern, "udat_toPattern#{suffix}", [:pointer, :bool , :pointer, :int32_t , :pointer], :int32_t
|
434
438
|
attach_function :udat_applyPattern, "udat_applyPattern#{suffix}", [:pointer, :bool , :pointer, :int32_t ], :void
|
439
|
+
# skeleton pattern
|
440
|
+
attach_function :udatpg_open, "udatpg_open#{suffix}", [:string, :pointer], :pointer
|
441
|
+
attach_function :udatpg_getBestPattern, "udatpg_getBestPattern#{suffix}", [:pointer, :pointer, :int32_t, :pointer, :int32_t, :pointer], :int32_t
|
435
442
|
# tz
|
436
443
|
attach_function :ucal_setDefaultTimeZone, "ucal_setDefaultTimeZone#{suffix}", [:pointer, :pointer], :int32_t
|
437
444
|
attach_function :ucal_getDefaultTimeZone, "ucal_getDefaultTimeZone#{suffix}", [:pointer, :int32_t, :pointer], :int32_t
|
@@ -68,8 +68,19 @@ module ICU
|
|
68
68
|
case number
|
69
69
|
when Float
|
70
70
|
needed_length = Lib.unum_format_double(@f, number, out_ptr, needed_length, nil, error)
|
71
|
-
when
|
72
|
-
|
71
|
+
when Integer
|
72
|
+
begin
|
73
|
+
# Try doing it fast, for integers that can be marshaled into an int64_t
|
74
|
+
needed_length = Lib.unum_format_int64(@f, number, out_ptr, needed_length, nil, error)
|
75
|
+
rescue RangeError
|
76
|
+
# Fall back to stringifying in Ruby and passing that to ICU
|
77
|
+
unless defined? Lib.unum_format_decimal
|
78
|
+
raise RangeError,"Number #{number} is too big to fit in int64_t and your "\
|
79
|
+
"ICU version is too old to have unum_format_decimal"
|
80
|
+
end
|
81
|
+
string_version = number.to_s
|
82
|
+
needed_length = Lib.unum_format_decimal(@f, string_version, string_version.bytesize, out_ptr, needed_length, nil, error)
|
83
|
+
end
|
73
84
|
when BigDecimal
|
74
85
|
string_version = number.to_s('F')
|
75
86
|
if Lib.respond_to? :unum_format_decimal
|
@@ -77,8 +88,6 @@ module ICU
|
|
77
88
|
else
|
78
89
|
needed_length = Lib.unum_format_double(@f, number.to_f, out_ptr, needed_length, nil, error)
|
79
90
|
end
|
80
|
-
when Bignum
|
81
|
-
needed_length = Lib.unum_format_int64(@f, number, out_ptr, needed_length, nil, error)
|
82
91
|
end
|
83
92
|
end
|
84
93
|
out_ptr.string needed_length
|
@@ -65,21 +65,31 @@ module ICU
|
|
65
65
|
|
66
66
|
private
|
67
67
|
|
68
|
-
def make_formatter(time_style, date_style, locale, time_zone_str)
|
69
|
-
time_zone
|
70
|
-
|
68
|
+
def make_formatter(time_style, date_style, locale, time_zone_str, skeleton)
|
69
|
+
time_zone = nil
|
70
|
+
tz_len = 0
|
71
|
+
pattern_len = -1
|
72
|
+
pattern_ptr = FFI::MemoryPointer.new(4)
|
73
|
+
|
71
74
|
if time_zone_str
|
72
75
|
time_zone = UCharPointer.from_string(time_zone_str)
|
73
|
-
|
76
|
+
tz_len = time_zone_str.size
|
74
77
|
else
|
75
78
|
Lib.check_error { | error|
|
76
79
|
i_len = 150
|
77
80
|
time_zone = UCharPointer.new(i_len)
|
78
|
-
|
81
|
+
tz_len = Lib.ucal_getDefaultTimeZone(time_zone, i_len, error)
|
79
82
|
}
|
80
83
|
end
|
81
84
|
|
82
|
-
|
85
|
+
if skeleton
|
86
|
+
date_style = :pattern
|
87
|
+
time_style = :pattern
|
88
|
+
|
89
|
+
pattern_len, pattern_ptr = skeleton_format(skeleton, locale)
|
90
|
+
end
|
91
|
+
|
92
|
+
ptr = Lib.check_error { | error| Lib.udat_open(time_style, date_style, locale, time_zone, tz_len, pattern_ptr, pattern_len, error) }
|
83
93
|
FFI::AutoPointer.new(ptr, Lib.method(:udat_close))
|
84
94
|
end
|
85
95
|
end
|
@@ -91,7 +101,9 @@ module ICU
|
|
91
101
|
locale = options[:locale] || 'C'
|
92
102
|
tz_style = options[:tz_style]
|
93
103
|
time_zone = options[:zone]
|
94
|
-
|
104
|
+
skeleton = options[:skeleton]
|
105
|
+
|
106
|
+
@f = make_formatter(time_style, date_style, locale, time_zone, skeleton)
|
95
107
|
if tz_style
|
96
108
|
f0 = date_format(true)
|
97
109
|
f1 = update_tz_format(f0, tz_style)
|
@@ -103,7 +115,7 @@ module ICU
|
|
103
115
|
|
104
116
|
def parse(str)
|
105
117
|
str_u = UCharPointer.from_string(str)
|
106
|
-
str_l =
|
118
|
+
str_l = str.size
|
107
119
|
Lib.check_error do |error|
|
108
120
|
ret = Lib.udat_parse(@f, str_u, str_l, nil, error)
|
109
121
|
Time.at(ret / 1000.0)
|
@@ -177,6 +189,32 @@ module ICU
|
|
177
189
|
needed_length = Lib.udat_applyPattern(@f, localized, pattern, pattern_len)
|
178
190
|
end
|
179
191
|
end
|
192
|
+
|
193
|
+
def skeleton_format(skeleton_pattern_str, locale)
|
194
|
+
skeleton_pattern_ptr = UCharPointer.from_string(skeleton_pattern_str)
|
195
|
+
skeleton_pattern_len = skeleton_pattern_str.size
|
196
|
+
|
197
|
+
needed_length = 0
|
198
|
+
pattern_ptr = UCharPointer.new(needed_length)
|
199
|
+
|
200
|
+
udatpg_ptr = Lib.check_error { |error| Lib.udatpg_open(locale, error) }
|
201
|
+
generator = FFI::AutoPointer.new(udatpg_ptr, Lib.method(:udat_close))
|
202
|
+
|
203
|
+
retried = false
|
204
|
+
|
205
|
+
begin
|
206
|
+
Lib.check_error do |error|
|
207
|
+
needed_length = Lib.udatpg_getBestPattern(generator, skeleton_pattern_ptr, skeleton_pattern_len, pattern_ptr, needed_length, error)
|
208
|
+
end
|
209
|
+
|
210
|
+
return needed_length, pattern_ptr
|
211
|
+
rescue BufferOverflowError
|
212
|
+
raise BufferOverflowError, "needed: #{needed_length}" if retried
|
213
|
+
pattern_ptr = pattern_ptr.resized_to needed_length
|
214
|
+
retried = true
|
215
|
+
retry
|
216
|
+
end
|
217
|
+
end
|
180
218
|
end # DateTimeFormatter
|
181
219
|
end # Formatting
|
182
220
|
end # ICU
|
data/lib/ffi-icu/version.rb
CHANGED
data/lib/ffi-icu.rb
CHANGED
data/spec/break_iterator_spec.rb
CHANGED
@@ -1,75 +1,76 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
3
|
module ICU
|
6
4
|
describe BreakIterator do
|
7
5
|
|
8
6
|
it "should return available locales" do
|
9
7
|
locales = ICU::BreakIterator.available_locales
|
10
|
-
locales.
|
11
|
-
locales.
|
12
|
-
locales.
|
8
|
+
expect(locales).to be_an(Array)
|
9
|
+
expect(locales).to_not be_empty
|
10
|
+
expect(locales).to include("en_US")
|
13
11
|
end
|
14
12
|
|
15
13
|
it "finds all word boundaries in an English string" do
|
16
14
|
iterator = BreakIterator.new :word, "en_US"
|
17
15
|
iterator.text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
|
18
|
-
iterator.to_a.
|
16
|
+
expect(iterator.to_a).to eq(
|
17
|
+
[0, 5, 6, 11, 12, 17, 18, 21, 22, 26, 27, 28, 39, 40, 51, 52, 56, 57, 58, 61, 62, 64, 65, 72, 73, 79, 80, 90, 91, 93, 94, 100, 101, 103, 104, 110, 111, 116, 117, 123, 124]
|
18
|
+
)
|
19
19
|
end
|
20
20
|
|
21
21
|
it "returns each substring" do
|
22
22
|
iterator = BreakIterator.new :word, "en_US"
|
23
23
|
iterator.text = "Lorem ipsum dolor sit amet."
|
24
24
|
|
25
|
-
iterator.substrings.
|
25
|
+
expect(iterator.substrings).to eq(["Lorem", " ", "ipsum", " ", "dolor", " ", "sit", " ", "amet", "."])
|
26
26
|
end
|
27
27
|
|
28
28
|
it "returns the substrings of a non-ASCII string" do
|
29
29
|
iterator = BreakIterator.new :word, "th_TH"
|
30
30
|
iterator.text = "รู้อะไรไม่สู้รู้วิชา รู้รักษาตัวรอดเป็นยอดดี"
|
31
31
|
|
32
|
-
iterator.substrings.
|
32
|
+
expect(iterator.substrings).to eq(
|
33
|
+
["รู้", "อะไร", "ไม่สู้", "รู้", "วิชา", " ", "รู้", "รักษา", "ตัว", "รอด", "เป็น", "ยอดดี"]
|
34
|
+
)
|
33
35
|
end
|
34
36
|
|
35
37
|
it "finds all word boundaries in a non-ASCII string" do
|
36
38
|
iterator = BreakIterator.new :word, "th_TH"
|
37
39
|
iterator.text = "การทดลอง"
|
38
|
-
iterator.to_a.
|
40
|
+
expect(iterator.to_a).to eq([0, 3, 8])
|
39
41
|
end
|
40
42
|
|
41
43
|
it "finds all sentence boundaries in an English string" do
|
42
44
|
iterator = BreakIterator.new :sentence, "en_US"
|
43
45
|
iterator.text = "This is a sentence. This is another sentence, with a comma in it."
|
44
|
-
iterator.to_a.
|
46
|
+
expect(iterator.to_a).to eq([0, 20, 65])
|
45
47
|
end
|
46
48
|
|
47
49
|
it "can navigate back and forward" do
|
48
50
|
iterator = BreakIterator.new :word, "en_US"
|
49
51
|
iterator.text = "Lorem ipsum dolor sit amet."
|
50
52
|
|
51
|
-
iterator.first.
|
53
|
+
expect(iterator.first).to eq(0)
|
52
54
|
iterator.next
|
53
|
-
iterator.current.
|
54
|
-
iterator.last.
|
55
|
+
expect(iterator.current).to eq(5)
|
56
|
+
expect(iterator.last).to eq(27)
|
55
57
|
end
|
56
58
|
|
57
59
|
it "fetches info about given offset" do
|
58
60
|
iterator = BreakIterator.new :word, "en_US"
|
59
61
|
iterator.text = "Lorem ipsum dolor sit amet."
|
60
62
|
|
61
|
-
iterator.following(3).
|
62
|
-
iterator.preceding(6).
|
63
|
+
expect(iterator.following(3)).to eq(5)
|
64
|
+
expect(iterator.preceding(6)).to eq(5)
|
63
65
|
|
64
|
-
iterator.
|
65
|
-
iterator.
|
66
|
+
expect(iterator).to be_boundary(5)
|
67
|
+
expect(iterator).to_not be_boundary(10)
|
66
68
|
end
|
67
69
|
|
68
70
|
it "returns an Enumerator if no block was given" do
|
69
71
|
iterator = BreakIterator.new :word, "nb"
|
70
|
-
expected = ICU.ruby19? ? Enumerator : Enumerable::Enumerator
|
71
72
|
|
72
|
-
iterator.each.
|
73
|
+
expect(iterator.each).to be_kind_of(Enumerator)
|
73
74
|
end
|
74
75
|
|
75
76
|
end # BreakIterator
|
data/spec/chardet_spec.rb
CHANGED
@@ -1,29 +1,27 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe ICU::CharDet::Detector do
|
6
4
|
|
7
5
|
let(:detector) { ICU::CharDet::Detector.new }
|
8
6
|
|
9
7
|
it "should recognize UTF-8" do
|
10
8
|
m = detector.detect("æåø")
|
11
|
-
m.name.
|
12
|
-
m.language.
|
9
|
+
expect(m.name).to eq("UTF-8")
|
10
|
+
expect(m.language).to be_a(String)
|
13
11
|
end
|
14
12
|
|
15
13
|
it "has a list of detectable charsets" do
|
16
14
|
cs = detector.detectable_charsets
|
17
|
-
cs.
|
18
|
-
cs.
|
15
|
+
expect(cs).to be_an(Array)
|
16
|
+
expect(cs).to_not be_empty
|
19
17
|
|
20
|
-
cs.first.
|
18
|
+
expect(cs.first).to be_a(String)
|
21
19
|
end
|
22
20
|
|
23
21
|
it "should disable / enable the input filter" do
|
24
|
-
detector.input_filter_enabled
|
22
|
+
expect(detector.input_filter_enabled?).to be_falsey
|
25
23
|
detector.input_filter_enabled = true
|
26
|
-
detector.input_filter_enabled
|
24
|
+
expect(detector.input_filter_enabled?).to be_truthy
|
27
25
|
end
|
28
26
|
|
29
27
|
it "should should set declared encoding" do
|
@@ -31,14 +29,14 @@ describe ICU::CharDet::Detector do
|
|
31
29
|
end
|
32
30
|
|
33
31
|
it "should detect several matching encodings" do
|
34
|
-
detector.detect_all("foo bar").
|
32
|
+
expect(detector.detect_all("foo bar")).to be_an(Array)
|
35
33
|
end
|
36
34
|
|
37
35
|
it "should support null bytes" do
|
38
36
|
# Create a utf-16 string and then force it to binary (ascii) to mimic data from net/http
|
39
37
|
string = "foo".encode("UTF-16").force_encoding("binary")
|
40
38
|
m = detector.detect(string)
|
41
|
-
m.name.
|
42
|
-
m.language.
|
39
|
+
expect(m.name).to eq("UTF-16BE")
|
40
|
+
expect(m.language).to be_a(String)
|
43
41
|
end
|
44
42
|
end
|
data/spec/collation_spec.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
module ICU
|
6
4
|
module Collation
|
7
5
|
describe "Collation" do
|
8
6
|
it "should collate an array of strings" do
|
9
|
-
Collation.collate("nb", %w[æ å ø]).
|
7
|
+
expect(Collation.collate("nb", %w[æ å ø])).to eq(%w[æ ø å])
|
10
8
|
end
|
11
9
|
end
|
12
10
|
|
@@ -14,51 +12,50 @@ module ICU
|
|
14
12
|
let(:collator) { Collator.new("nb") }
|
15
13
|
|
16
14
|
it "should collate an array of strings" do
|
17
|
-
collator.collate(%w[å ø æ]).
|
15
|
+
expect(collator.collate(%w[å ø æ])).to eq(%w[æ ø å])
|
18
16
|
end
|
19
17
|
|
20
18
|
it "raises an error if argument does not respond to :sort" do
|
21
|
-
|
19
|
+
expect { collator.collate(1) }.to raise_error(ArgumentError)
|
22
20
|
end
|
23
21
|
|
24
22
|
it "should return available locales" do
|
25
23
|
locales = ICU::Collation.available_locales
|
26
|
-
locales.
|
27
|
-
locales.
|
28
|
-
locales.
|
24
|
+
expect(locales).to be_an(Array)
|
25
|
+
expect(locales).to_not be_empty
|
26
|
+
expect(locales).to include("nb")
|
29
27
|
end
|
30
28
|
|
31
29
|
it "should return the locale of the collator" do
|
32
|
-
|
33
|
-
l.should == "nb"
|
30
|
+
expect(collator.locale).to eq('nb')
|
34
31
|
end
|
35
32
|
|
36
33
|
it "should compare two strings" do
|
37
|
-
collator.compare("blåbærsyltetøy", "blah").
|
38
|
-
collator.compare("blah", "blah").
|
39
|
-
collator.compare("ba", "bl").
|
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)
|
40
37
|
end
|
41
38
|
|
42
39
|
it "should know if a string is greater than another" do
|
43
|
-
collator.
|
44
|
-
collator.
|
40
|
+
expect(collator).to be_greater("z", "a")
|
41
|
+
expect(collator).to_not be_greater("a", "z")
|
45
42
|
end
|
46
43
|
|
47
44
|
it "should know if a string is greater or equal to another" do
|
48
|
-
collator.
|
49
|
-
collator.
|
50
|
-
collator.
|
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")
|
51
48
|
end
|
52
49
|
|
53
50
|
it "should know if a string is equal to another" do
|
54
|
-
collator.
|
55
|
-
collator.
|
51
|
+
expect(collator).to be_equal("a", "a")
|
52
|
+
expect(collator).to_not be_equal("a", "b")
|
56
53
|
end
|
57
54
|
|
58
55
|
it "should return rules" do
|
59
|
-
collator.rules.
|
56
|
+
expect(collator.rules).to_not be_empty
|
60
57
|
# ö sorts before Ö
|
61
|
-
collator.rules.include
|
58
|
+
expect(collator.rules).to include('ö<<<Ö')
|
62
59
|
end
|
63
60
|
|
64
61
|
end
|
@@ -1,14 +1,19 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
module ICU
|
6
4
|
module Lib
|
7
5
|
describe VersionInfo do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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.]+$/) }
|
12
17
|
end
|
13
18
|
end
|
14
19
|
end
|
data/spec/lib_spec.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
module ICU
|
6
4
|
describe Lib do
|
7
5
|
describe 'error checking' do
|
@@ -9,8 +7,8 @@ module ICU
|
|
9
7
|
|
10
8
|
context 'upon success' do
|
11
9
|
it 'returns the block result' do
|
12
|
-
Lib.check_error { |status| return_value }.
|
13
|
-
Lib.check_error { |status| status.write_int(0); return_value }.
|
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)
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
@@ -28,8 +26,9 @@ module ICU
|
|
28
26
|
before(:each) { $VERBOSE = true }
|
29
27
|
|
30
28
|
it 'prints to STDERR and returns the block result' do
|
31
|
-
$stderr.
|
32
|
-
Lib.check_error { |status| status.write_int(-127); return_value }
|
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)
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
@@ -37,8 +36,9 @@ module ICU
|
|
37
36
|
before(:each) { $VERBOSE = false }
|
38
37
|
|
39
38
|
it 'returns the block result' do
|
40
|
-
$stderr.
|
41
|
-
Lib.check_error { |status| status.write_int(-127); return_value }
|
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
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -49,15 +49,15 @@ module ICU
|
|
49
49
|
subject { Lib.cldr_version }
|
50
50
|
|
51
51
|
it { should be_a Lib::VersionInfo }
|
52
|
-
it('is populated') { subject.to_a.
|
52
|
+
it('is populated') { expect(subject.to_a).to_not eq([0,0,0,0]) }
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
describe 'ICU version' do
|
57
57
|
subject { Lib.version }
|
58
58
|
|
59
|
-
it {
|
60
|
-
it('is populated') { subject.to_a.
|
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
61
|
end
|
62
62
|
end
|
63
63
|
end
|