ffi-icu 0.2.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/erickguan/ffi-icu.svg?branch=master)](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
|