twitter_cldr 1.4.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. data/NOTICE +36 -2
  2. data/README.md +2 -2
  3. data/lib/twitter_cldr/collation/collator.rb +143 -0
  4. data/lib/twitter_cldr/collation/implicit_collation_elements.rb +188 -0
  5. data/lib/twitter_cldr/collation/sort_key.rb +199 -0
  6. data/lib/twitter_cldr/collation/trie.rb +73 -0
  7. data/lib/twitter_cldr/collation/trie_builder.rb +56 -0
  8. data/lib/twitter_cldr/collation.rb +14 -0
  9. data/lib/twitter_cldr/core_ext/localized_object.rb +3 -2
  10. data/lib/twitter_cldr/core_ext/string.rb +1 -1
  11. data/lib/twitter_cldr/formatters/calendars/datetime_formatter.rb +89 -72
  12. data/lib/twitter_cldr/normalization/base.rb +22 -0
  13. data/lib/twitter_cldr/normalization/hangul.rb +68 -0
  14. data/lib/twitter_cldr/{normalizers → normalization}/nfc.rb +2 -2
  15. data/lib/twitter_cldr/{normalizers → normalization}/nfd.rb +1 -1
  16. data/lib/twitter_cldr/{normalizers → normalization}/nfkc.rb +5 -17
  17. data/lib/twitter_cldr/{normalizers → normalization}/nfkd.rb +3 -18
  18. data/lib/twitter_cldr/normalization.rb +15 -0
  19. data/lib/twitter_cldr/shared/code_point.rb +5 -3
  20. data/lib/twitter_cldr/tokenizers/base.rb +15 -1
  21. data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +6 -1
  22. data/lib/twitter_cldr/utils/code_points.rb +1 -1
  23. data/lib/twitter_cldr/version.rb +2 -2
  24. data/lib/twitter_cldr.rb +9 -8
  25. data/resources/collation/FractionalUCA_SHORT.txt +41593 -0
  26. data/resources/locales/af/calendars.yml +164 -0
  27. data/resources/locales/af/languages.yml +173 -0
  28. data/resources/locales/af/numbers.yml +42 -0
  29. data/resources/locales/af/plurals.yml +2 -0
  30. data/resources/locales/af/units.yml +88 -0
  31. data/resources/locales/ar/calendars.yml +9 -0
  32. data/resources/locales/ar/numbers.yml +15 -2
  33. data/resources/locales/ca/calendars.yml +228 -0
  34. data/resources/locales/ca/languages.yml +510 -0
  35. data/resources/locales/ca/numbers.yml +43 -0
  36. data/resources/locales/ca/plurals.yml +2 -0
  37. data/resources/locales/ca/units.yml +93 -0
  38. data/resources/locales/cs/calendars.yml +229 -0
  39. data/resources/locales/cs/languages.yml +471 -0
  40. data/resources/locales/cs/numbers.yml +44 -0
  41. data/resources/locales/cs/plurals.yml +2 -0
  42. data/resources/locales/cs/units.yml +114 -0
  43. data/resources/locales/da/calendars.yml +10 -0
  44. data/resources/locales/da/numbers.yml +13 -0
  45. data/resources/locales/de/calendars.yml +9 -0
  46. data/resources/locales/de/numbers.yml +13 -0
  47. data/resources/locales/el/calendars.yml +227 -0
  48. data/resources/locales/el/languages.yml +519 -0
  49. data/resources/locales/el/numbers.yml +42 -0
  50. data/resources/locales/el/plurals.yml +2 -0
  51. data/resources/locales/el/units.yml +107 -0
  52. data/resources/locales/en/calendars.yml +10 -0
  53. data/resources/locales/en/numbers.yml +13 -0
  54. data/resources/locales/es/calendars.yml +9 -0
  55. data/resources/locales/es/numbers.yml +13 -0
  56. data/resources/locales/eu/calendars.yml +173 -0
  57. data/resources/locales/eu/languages.yml +161 -0
  58. data/resources/locales/eu/numbers.yml +43 -0
  59. data/resources/locales/eu/plurals.yml +2 -0
  60. data/resources/locales/eu/units.yml +91 -0
  61. data/resources/locales/fa/calendars.yml +10 -0
  62. data/resources/locales/fa/numbers.yml +13 -0
  63. data/resources/locales/fi/calendars.yml +10 -0
  64. data/resources/locales/fi/numbers.yml +14 -1
  65. data/resources/locales/fil/calendars.yml +8 -0
  66. data/resources/locales/fil/numbers.yml +13 -0
  67. data/resources/locales/fr/calendars.yml +9 -0
  68. data/resources/locales/fr/numbers.yml +14 -1
  69. data/resources/locales/he/calendars.yml +9 -0
  70. data/resources/locales/he/numbers.yml +13 -0
  71. data/resources/locales/hi/calendars.yml +8 -0
  72. data/resources/locales/hi/numbers.yml +13 -0
  73. data/resources/locales/hu/calendars.yml +10 -0
  74. data/resources/locales/hu/numbers.yml +15 -2
  75. data/resources/locales/id/calendars.yml +8 -0
  76. data/resources/locales/id/numbers.yml +16 -3
  77. data/resources/locales/it/calendars.yml +9 -0
  78. data/resources/locales/it/numbers.yml +13 -0
  79. data/resources/locales/ja/calendars.yml +9 -0
  80. data/resources/locales/ja/numbers.yml +13 -0
  81. data/resources/locales/ko/calendars.yml +9 -0
  82. data/resources/locales/ko/numbers.yml +13 -0
  83. data/resources/locales/ms/calendars.yml +8 -0
  84. data/resources/locales/ms/numbers.yml +16 -3
  85. data/resources/locales/nb/calendars.yml +234 -0
  86. data/resources/locales/{no → nb}/languages.yml +25 -4
  87. data/resources/locales/nb/numbers.yml +43 -0
  88. data/resources/locales/nb/plurals.yml +2 -0
  89. data/resources/locales/nb/units.yml +87 -0
  90. data/resources/locales/nl/calendars.yml +10 -0
  91. data/resources/locales/nl/numbers.yml +13 -0
  92. data/resources/locales/pl/calendars.yml +9 -0
  93. data/resources/locales/pl/numbers.yml +14 -1
  94. data/resources/locales/pt/calendars.yml +9 -0
  95. data/resources/locales/pt/numbers.yml +13 -0
  96. data/resources/locales/ru/calendars.yml +10 -0
  97. data/resources/locales/ru/numbers.yml +14 -1
  98. data/resources/locales/sv/calendars.yml +10 -0
  99. data/resources/locales/sv/numbers.yml +14 -1
  100. data/resources/locales/th/calendars.yml +67 -57
  101. data/resources/locales/th/numbers.yml +13 -0
  102. data/resources/locales/tr/calendars.yml +9 -0
  103. data/resources/locales/tr/numbers.yml +13 -0
  104. data/resources/locales/uk/calendars.yml +199 -0
  105. data/resources/locales/uk/languages.yml +519 -0
  106. data/resources/locales/uk/numbers.yml +45 -0
  107. data/resources/locales/uk/plurals.yml +2 -0
  108. data/resources/locales/uk/units.yml +135 -0
  109. data/resources/locales/ur/calendars.yml +9 -0
  110. data/resources/locales/ur/numbers.yml +13 -0
  111. data/resources/locales/zh/calendars.yml +8 -0
  112. data/resources/locales/zh/numbers.yml +13 -0
  113. data/resources/locales/zh-Hant/calendars.yml +8 -0
  114. data/resources/locales/zh-Hant/numbers.yml +16 -3
  115. data/resources/locales/zh-Hant/plurals.yml +2 -0
  116. data/resources/unicode_data/hangul_blocks.yml +21 -0
  117. data/spec/collation/CollationTest_CLDR_NON_IGNORABLE_Short.txt +714 -0
  118. data/spec/collation/collation_spec.rb +93 -0
  119. data/spec/collation/collator_spec.rb +117 -0
  120. data/spec/collation/implicit_collation_elements_spec.rb +24 -0
  121. data/spec/collation/sort_key_spec.rb +56 -0
  122. data/spec/collation/trie_builder_spec.rb +114 -0
  123. data/spec/collation/trie_spec.rb +97 -0
  124. data/spec/core_ext/calendars/datetime_spec.rb +5 -0
  125. data/spec/core_ext/calendars_spec.rb +34 -0
  126. data/spec/core_ext/numbers_spec.rb +39 -0
  127. data/spec/core_ext/string_spec.rb +4 -4
  128. data/spec/formatters/calendars/datetime_formatter_spec.rb +92 -2
  129. data/spec/{normalizers → normalization}/NormalizationTestShort.txt +0 -0
  130. data/spec/{normalizers → normalization}/base_spec.rb +1 -1
  131. data/spec/normalization/hangul_spec.rb +42 -0
  132. data/spec/{normalizers → normalization}/normalization_spec.rb +15 -16
  133. data/spec/readme_spec.rb +2 -2
  134. data/spec/shared/code_point_spec.rb +42 -30
  135. data/spec/shared/resources_spec.rb +30 -6
  136. data/spec/tokenizers/base_spec.rb +17 -0
  137. data/spec/twitter_cldr_spec.rb +1 -1
  138. metadata +71 -83
  139. data/lib/twitter_cldr/normalizers/base.rb +0 -34
  140. data/lib/twitter_cldr/normalizers.rb +0 -14
  141. data/resources/locales/no/calendars.yml +0 -127
  142. data/resources/locales/no/numbers.yml +0 -29
  143. data/resources/locales/no/plurals.yml +0 -1
  144. data/resources/unicode_data/blocks_hangul.yml +0 -46
  145. data/spec/normalizers/NormalizationTest.txt +0 -18431
@@ -24,10 +24,74 @@ describe DateTimeFormatter do
24
24
  end
25
25
  end
26
26
 
27
+ describe "#weekday_local_stand_alone" do
28
+ it "test: pattern c" do
29
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 4), 'c', 1).should == '1'
30
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 5), 'c', 1).should == '2'
31
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 10), 'c', 1).should == '7'
32
+ end
33
+
34
+ it "test: pattern cc" do
35
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 4), 'cc', 2).should == 'Mo.'
36
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 5), 'cc', 2).should == 'Di.'
37
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 10), 'cc', 2).should == 'So.'
38
+ end
39
+
40
+ it "test: pattern ccc" do
41
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 4), 'ccc', 3).should == 'Mo.'
42
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 5), 'ccc', 3).should == 'Di.'
43
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 10), 'ccc', 3).should == 'So.'
44
+ end
45
+
46
+ it "test: pattern cccc" do
47
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 4), 'cccc', 4).should == 'Montag'
48
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 5), 'cccc', 4).should == 'Dienstag'
49
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 10), 'cccc', 4).should == 'Sonntag'
50
+ end
51
+
52
+ it "test: pattern ccccc" do
53
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 4), 'ccccc', 5).should == 'M'
54
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 5), 'ccccc', 5).should == 'D'
55
+ @formatter.send(:weekday_local_stand_alone, Date.new(2010, 1, 10), 'ccccc', 5).should == 'S'
56
+ end
57
+ end
58
+
59
+ describe "#weekday_local" do
60
+ it "test: pattern e" do
61
+ @formatter.send(:weekday_local, Date.new(2010, 1, 4), 'e', 1).should == '1'
62
+ @formatter.send(:weekday_local, Date.new(2010, 1, 5), 'e', 1).should == '2'
63
+ @formatter.send(:weekday_local, Date.new(2010, 1, 10), 'e', 1).should == '7'
64
+ end
65
+
66
+ it "test: pattern ee" do
67
+ @formatter.send(:weekday_local, Date.new(2010, 1, 4), 'ee', 2).should == '1'
68
+ @formatter.send(:weekday_local, Date.new(2010, 1, 5), 'ee', 2).should == '2'
69
+ @formatter.send(:weekday_local, Date.new(2010, 1, 10), 'ee', 2).should == '7'
70
+ end
71
+
72
+ it "test: pattern eee" do
73
+ @formatter.send(:weekday_local, Date.new(2010, 1, 4), 'eee', 3).should == 'Mo.'
74
+ @formatter.send(:weekday_local, Date.new(2010, 1, 5), 'eee', 3).should == 'Di.'
75
+ @formatter.send(:weekday_local, Date.new(2010, 1, 10), 'eee', 3).should == 'So.'
76
+ end
77
+
78
+ it "test: pattern eeee" do
79
+ @formatter.send(:weekday_local, Date.new(2010, 1, 4), 'eeee', 4).should == 'Montag'
80
+ @formatter.send(:weekday_local, Date.new(2010, 1, 5), 'eeee', 4).should == 'Dienstag'
81
+ @formatter.send(:weekday_local, Date.new(2010, 1, 10), 'eeee', 4).should == 'Sonntag'
82
+ end
83
+
84
+ it "test: pattern eeeee" do
85
+ @formatter.send(:weekday_local, Date.new(2010, 1, 4), 'eeeee', 5).should == 'M'
86
+ @formatter.send(:weekday_local, Date.new(2010, 1, 5), 'eeeee', 5).should == 'D'
87
+ @formatter.send(:weekday_local, Date.new(2010, 1, 10), 'eeeee', 5).should == 'S'
88
+ end
89
+ end
90
+
27
91
  describe "#weekday" do
28
92
  it "test: pattern E, EE, EEE" do
29
- @formatter.send(:weekday, Date.new(2010, 1, 1), 'E', 1).should == 'Fr.'
30
- @formatter.send(:weekday, Date.new(2010, 1, 1), 'EE', 2).should == 'Fr.'
93
+ @formatter.send(:weekday, Date.new(2010, 1, 1), 'E', 1).should == 'Fr.'
94
+ @formatter.send(:weekday, Date.new(2010, 1, 1), 'EE', 2).should == 'Fr.'
31
95
  @formatter.send(:weekday, Date.new(2010, 1, 1), 'EEE', 3).should == 'Fr.'
32
96
  end
33
97
 
@@ -327,4 +391,30 @@ describe DateTimeFormatter do
327
391
  @formatter.send(:year, Date.new(12345, 1, 1), 'yyyyy', 5).should == '12345'
328
392
  end
329
393
  end
394
+
395
+ describe "#era" do
396
+ before(:each) do
397
+ @formatter = DateTimeFormatter.new(:locale => :en)
398
+ end
399
+
400
+ it "test: pattern G" do
401
+ @formatter.send(:era, Date.new(2012, 1, 1), 'G', 1).should == "AD"
402
+ @formatter.send(:era, Date.new(-1, 1, 1), 'G', 1).should == "BC"
403
+ end
404
+
405
+ it "test: pattern GG" do
406
+ @formatter.send(:era, Date.new(2012, 1, 1), 'GG', 2).should == "AD"
407
+ @formatter.send(:era, Date.new(-1, 1, 1), 'GG', 2).should == "BC"
408
+ end
409
+
410
+ it "test: pattern GGG" do
411
+ @formatter.send(:era, Date.new(2012, 1, 1), 'GGG', 3).should == "AD"
412
+ @formatter.send(:era, Date.new(-1, 1, 1), 'GGG', 3).should == "BC"
413
+ end
414
+
415
+ it "test: pattern GGGG" do
416
+ @formatter.send(:era, Date.new(2012, 1, 1), 'GGGG', 4).should == "Anno Domini"
417
+ @formatter.send(:era, Date.new(-1, 1, 1), 'GGGG', 4).should == "Before Christ"
418
+ end
419
+ end
330
420
  end
@@ -5,7 +5,7 @@
5
5
 
6
6
  require 'spec_helper'
7
7
 
8
- include TwitterCldr::Normalizers
8
+ include TwitterCldr::Normalization
9
9
 
10
10
  describe Base do
11
11
  describe "#combining_class_for" do
@@ -0,0 +1,42 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ require 'spec_helper'
7
+
8
+ include TwitterCldr::Normalization
9
+
10
+ describe Hangul do
11
+
12
+ describe ".compose" do
13
+ it 'composes decomposed Hangul syllable without a trailing consonant' do
14
+ Hangul.compose([0x1101, 0x1167]).should == 0xAEF4
15
+ end
16
+
17
+ it 'composes decomposed Hangul syllable with a trailing consonant' do
18
+ Hangul.compose([0x1111, 0x1171, 0x11B6]).should == 0xD4DB
19
+ end
20
+ end
21
+
22
+ describe ".decompose" do
23
+ it 'decomposes precomposed Hangul syllable without a trailing consonant' do
24
+ Hangul.decompose(0xAEF4).should == [0x1101, 0x1167]
25
+ end
26
+
27
+ it 'decomposes precomposed Hangul syllable with a trailing consonant' do
28
+ Hangul.decompose(0xD4DB).should == [0x1111, 0x1171, 0x11B6]
29
+ end
30
+ end
31
+
32
+ describe '.hangul_syllable?' do
33
+ it 'returns true for code points from Hangul syllables range' do
34
+ [0xAC00, 0xAC01, 0xBC9F, 0xD7A1, 0xD7A3].map { |code_point| Hangul.hangul_syllable?(code_point).should be_true }
35
+ end
36
+
37
+ it 'returns false for other code points' do
38
+ [0xAB, 0xABFF, 0xD7A4, 0xFFCF].map { |code_point| Hangul.hangul_syllable?(code_point).should be_false }
39
+ end
40
+ end
41
+
42
+ end
@@ -7,24 +7,23 @@ require 'spec_helper'
7
7
 
8
8
  require 'open-uri'
9
9
 
10
- include TwitterCldr::Normalizers
10
+ include TwitterCldr::Normalization
11
11
 
12
12
  describe 'Unicode Normalization Algorithms' do
13
13
 
14
- NORMALIZERS_SPEC_PATH = File.dirname(__FILE__)
15
- SHORT_TEST_PATH = File.join(NORMALIZERS_SPEC_PATH, 'NormalizationTestShort.txt')
16
- FULL_TEST_PATH = File.join(NORMALIZERS_SPEC_PATH, 'NormalizationTest.txt')
14
+ SHORT_NORMALIZATION_TEST_PATH = File.join(File.dirname(__FILE__), 'NormalizationTestShort.txt')
15
+ FULL_NORMALIZATION_TEST_PATH = File.join(File.dirname(__FILE__), 'NormalizationTest.txt')
17
16
 
18
- NORMALIZATION_TEST_URL = 'http://unicode.org/Public/UNIDATA/NormalizationTest.txt'
17
+ FULL_NORMALIZATION_TEST_URL = 'http://unicode.org/Public/UNIDATA/NormalizationTest.txt'
19
18
 
20
19
  shared_examples_for 'a normalization algorithm' do
21
- it 'passes all the tests in NormalizersTestShort.txt' do
22
- run_normalization_test(described_class, invariants, SHORT_TEST_PATH)
20
+ it 'passes all the tests in NormalizationTestShort.txt' do
21
+ run_test(described_class, invariants, SHORT_NORMALIZATION_TEST_PATH)
23
22
  end
24
23
 
25
- it 'passes all the tests in NormalizersTest.txt', :slow => true do
24
+ it 'passes all the tests in NormalizationTest.txt', :slow => true do
26
25
  prepare_full_test
27
- run_normalization_test(described_class, invariants, FULL_TEST_PATH)
26
+ run_test(described_class, invariants, FULL_NORMALIZATION_TEST_PATH)
28
27
  end
29
28
  end
30
29
 
@@ -59,7 +58,7 @@ describe 'Unicode Normalization Algorithms' do
59
58
  # where (c1, c2,...) are columns of the normalization test separated by semicolons and normalized() is the
60
59
  # normalization function. Note, how expectation and tests columns indexes match the numbers in the `invariants` hash.
61
60
  #
62
- def run_normalization_test(normalizer, invariants, file_path)
61
+ def run_test(normalizer, invariants, file_path)
63
62
  open(file_path, 'r:UTF-8') do |file|
64
63
  file.each do |line|
65
64
  next if line.empty? || line =~ /^(@|#)/
@@ -74,7 +73,7 @@ describe 'Unicode Normalization Algorithms' do
74
73
 
75
74
  normalized = normalizer.normalize_code_points(test)
76
75
 
77
- message = normalization_error_message(line, test, expected, normalized, test_index, expected_index)
76
+ message = error_message(line, test, expected, normalized, test_index, expected_index)
78
77
  normalized.should(eq(expected), message)
79
78
  end
80
79
  end
@@ -82,9 +81,9 @@ describe 'Unicode Normalization Algorithms' do
82
81
  end
83
82
  end
84
83
 
85
- # Generates helpful error message for normalization test failure.
84
+ # Generates a descriptive error message test failure.
86
85
  #
87
- def normalization_error_message(line, test, expected, normalized, test_index, expected_index)
86
+ def error_message(line, test, expected, normalized, test_index, expected_index)
88
87
  <<-END
89
88
  Test: "#{line.strip}"
90
89
  Invariant: normalized(c#{test_index}) == c#{expected_index}
@@ -93,13 +92,13 @@ Got: #{normalized.inspect}
93
92
  END
94
93
  end
95
94
 
96
- # Downloads full Unicode normalization tests suit if necessary.
95
+ # Downloads full version of the test if necessary.
97
96
  #
98
97
  def prepare_full_test
99
- return if File.file?(FULL_TEST_PATH)
98
+ return if File.file?(FULL_NORMALIZATION_TEST_PATH)
100
99
 
101
100
  print ' Downloading NormalizationTest.txt ... '
102
- open(FULL_TEST_PATH, 'w') { |file| file.write(open(NORMALIZATION_TEST_URL).read) }
101
+ open(FULL_NORMALIZATION_TEST_PATH, 'w') { |file| file.write(open(FULL_NORMALIZATION_TEST_URL).read) }
103
102
  puts 'done.'
104
103
  end
105
104
 
data/spec/readme_spec.rb CHANGED
@@ -188,9 +188,9 @@ describe "README" do
188
188
  end
189
189
 
190
190
  it "verifies normalization" do
191
- TwitterCldr::Normalizers::NFD.normalize("français").should == TwitterCldr::Utils::CodePoints.to_string(["0066", "0072", "0061", "006E", "0063", "0327", "0061", "0069", "0073"])
191
+ TwitterCldr::Normalization::NFD.normalize("français").should == TwitterCldr::Utils::CodePoints.to_string(["0066", "0072", "0061", "006E", "0063", "0327", "0061", "0069", "0073"])
192
192
  TwitterCldr::Utils::CodePoints.from_string("español").should == ["0065", "0073", "0070", "0061", "00F1", "006F", "006C"]
193
- TwitterCldr::Utils::CodePoints.from_string(TwitterCldr::Normalizers::NFD.normalize("español")).should == ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
193
+ TwitterCldr::Utils::CodePoints.from_string(TwitterCldr::Normalization::NFD.normalize("español")).should == ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
194
194
 
195
195
  "español".localize.code_points.should == ["0065", "0073", "0070", "0061", "00F1", "006F", "006C"]
196
196
  "español".localize.normalize.code_points.should == ["0065", "0073", "0070", "0061", "006E", "0303", "006F", "006C"]
@@ -16,39 +16,49 @@ describe CodePoint do
16
16
  end
17
17
 
18
18
  it "should return nil for invalid code points" do
19
- CodePoint.for_hex('abcd').should be_nil
19
+ CodePoint.for_hex('xyz').should be_nil
20
20
  CodePoint.for_hex('FFFFFFF').should be_nil
21
21
  CodePoint.for_hex('uytukhil123').should be_nil
22
22
  end
23
23
 
24
+ it "works with strings in a lower case" do
25
+ test_code_points_data(
26
+ "abcd" => ["ABCD", "MEETEI MAYEK LETTER HUK", "Lo", "0", "L", "", "", "", "", "N", "", "", "", "", ""]
27
+ )
28
+ end
29
+
30
+ it "works with strings shorter than 4 characters (by left-padding them with zeros)" do
31
+ test_code_points_data(
32
+ '306' => ['0306', 'COMBINING BREVE', 'Mn', '230', 'NSM', '', '', '', '', 'N', 'NON-SPACING BREVE', '', '', '', '']
33
+ )
34
+ end
35
+
24
36
  it "fetches valid information for the specified code point" do
25
- test_data = {
26
- '17D1' => ['17D1','KHMER SIGN VIRIAM','Mn','0','NSM',"","","","",'N',"","","","",""],
27
- 'FE91' => ['FE91','ARABIC LETTER BEH INITIAL FORM','Lo','0','AL','<initial> 0628',"","","",'N','GLYPH FOR INITIAL ARABIC BAA',"","","",""],
28
- '24B5' => ['24B5','PARENTHESIZED LATIN SMALL LETTER Z','So','0','L','<compat> 0028 007A 0029',"","","",'N',"","","","",""],
29
- '2128' => ['2128','BLACK-LETTER CAPITAL Z','Lu','0','L','<font> 005A',"","","",'N','BLACK-LETTER Z',"","","",""],
30
- '1F241'=> ['1F241','TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09','So','0','L','<compat> 3014 4E09 3015',"","","",'N',"","","","",""]
31
- }
32
- test_data.each_pair do |code_point, data|
33
- cp_data = CodePoint.for_hex(code_point)
34
- cp_data.code_point.should == data[0]
35
- cp_data.name.should == data[1]
36
- cp_data.category.should == data[2]
37
- cp_data.combining_class.should == data[3]
38
- end
37
+ test_code_points_data(
38
+ '17D1' => ['17D1', 'KHMER SIGN VIRIAM', 'Mn', '0', 'NSM', "", "", "", "", 'N', "", "", "", "", ""],
39
+ 'FE91' => ['FE91', 'ARABIC LETTER BEH INITIAL FORM', 'Lo', '0', 'AL', '<initial> 0628', "", "", "", 'N', 'GLYPH FOR INITIAL ARABIC BAA', "", "", "", ""],
40
+ '24B5' => ['24B5', 'PARENTHESIZED LATIN SMALL LETTER Z', 'So', '0', 'L', '<compat> 0028 007A 0029', "", "", "", 'N', "", "", "", "", ""],
41
+ '2128' => ['2128', 'BLACK-LETTER CAPITAL Z', 'Lu', '0', 'L', '<font> 005A', "", "", "", 'N', 'BLACK-LETTER Z', "", "", "", ""],
42
+ '1F241' => ['1F241', 'TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09', 'So', '0', 'L', '<compat> 3014 4E09 3015', "", "", "", 'N', "", "", "", "", ""]
43
+ )
39
44
  end
40
45
 
41
46
  it "fetches valid information for a code point within a range" do
42
- test_data = {
43
- '4E11' => ["4E11","<CJK Ideograph>","Lo","0","L","","","","","N","","","","",""],
44
- 'AC55' => ["AC55","<Hangul Syllable>","Lo","0","L","","","","","N","","","","",""],
45
- 'D7A1' => ["D7A1","<Hangul Syllable>","Lo","0","L","","","","","N","","","","",""],
46
- 'DAAA' => ["DAAA","<Non Private Use High Surrogate>","Cs","0","L","","","","","N","","","","",""],
47
- 'F8FE' => ["F8FE","<Private Use>","Co","0","L","","","","","N","","","","",""]
48
- }
47
+ test_code_points_data(
48
+ '4E11' => ["4E11", "<CJK Ideograph>", "Lo", "0", "L", "", "", "", "", "N", "", "", "", "", ""],
49
+ 'AC55' => ["AC55", "<Hangul Syllable>", "Lo", "0", "L", "", "", "", "", "N", "", "", "", "", ""],
50
+ 'D7A1' => ["D7A1", "<Hangul Syllable>", "Lo", "0", "L", "", "", "", "", "N", "", "", "", "", ""],
51
+ 'DAAA' => ["DAAA", "<Non Private Use High Surrogate>", "Cs", "0", "L", "", "", "", "", "N", "", "", "", "", ""],
52
+ 'F8FE' => ["F8FE", "<Private Use>", "Co", "0", "L", "", "", "", "", "N", "", "", "", "", ""]
53
+ )
54
+ end
49
55
 
50
- test_data.each_pair do |code_point, data|
56
+ def test_code_points_data(test_data)
57
+ test_data.each do |code_point, data|
51
58
  cp_data = CodePoint.for_hex(code_point)
59
+
60
+ cp_data.should_not be_nil
61
+
52
62
  cp_data.code_point.should == data[0]
53
63
  cp_data.name.should == data[1]
54
64
  cp_data.category.should == data[2]
@@ -94,11 +104,14 @@ describe CodePoint do
94
104
 
95
105
  describe "#hangul_type" do
96
106
  before(:each) do
97
- stub(CodePoint).hangul_blocks { { :lparts => [1..10],
98
- :vparts => [21..30],
99
- :tparts => [41..50],
100
- :compositions => [1..30],
101
- :decompositions => [31..50] } }
107
+ stub(CodePoint).hangul_blocks {
108
+ {
109
+ :lparts => [1..10],
110
+ :vparts => [21..30],
111
+ :tparts => [41..50],
112
+ :compositions => [1..50]
113
+ }
114
+ }
102
115
  end
103
116
 
104
117
  it "returns nil if not part of a hangul block" do
@@ -111,9 +124,8 @@ describe CodePoint do
111
124
  CodePoint.hangul_type(41.to_s(16)).should == :tparts
112
125
  end
113
126
 
114
- it "returns composition or decomposition if no part can be found" do
127
+ it "returns composition if no part can be found" do
115
128
  CodePoint.hangul_type(11.to_s(16)).should == :compositions
116
- CodePoint.hangul_type(40.to_s(16)).should == :decompositions
117
129
  end
118
130
  end
119
131
 
@@ -11,17 +11,26 @@ describe Resources do
11
11
  let(:resources) { Resources.new }
12
12
 
13
13
  describe '#get_resource' do
14
+ let(:resource_path) { 'random/resource.yml' }
15
+ let(:resource_content) { 'random YAML content' }
16
+
14
17
  it 'loads the correct YAML file' do
15
- stub(File).read(File.join(TwitterCldr::RESOURCES_DIR, 'shared/currencies.yml')) { "---\n- 1\n- 2\n" }
16
- resources.get_resource(:shared, :currencies).should == [1, 2]
18
+ stub_resource_file(resource_path, "---\n- 1\n- 2\n")
19
+ resources.get_resource(:random, :resource).should == [1, 2]
20
+ end
21
+
22
+ it 'symbolizes hash keys' do
23
+ stub_resource_file(resource_path, "---\na:\n b: 3\n")
24
+ resources.get_resource(:random, :resource).should == { :a => { :b => 3 } }
17
25
  end
18
26
 
19
27
  it 'loads the resource only once' do
20
- mock(resources).load_resource('shared/currencies.yml').once { 'foo-bar-baz' }
28
+ mock(resources).load_resource(resource_path).once { resource_content }
21
29
 
22
- result = resources.get_resource(:shared, :currencies)
30
+ result = resources.get_resource(:random, :resource)
31
+ result.should == resource_content
23
32
  # second time load_resource is not called but we get the same object as before
24
- resources.get_resource(:shared, :currencies).object_id.should == result.object_id
33
+ resources.get_resource(:random, :resource).object_id.should == result.object_id
25
34
  end
26
35
 
27
36
  it 'accepts a variable length resource path both in symbols and strings' do
@@ -30,16 +39,25 @@ describe Resources do
30
39
  end
31
40
 
32
41
  it 'raises an exception if resource file is missing' do
42
+ mock(File).file?(File.join(TwitterCldr::RESOURCES_DIR, 'foo/bar.yml')) { false }
33
43
  lambda { resources.get_resource(:foo, :bar) }.should raise_error(ArgumentError, "Resource 'foo/bar.yml' not found.")
34
44
  end
35
45
  end
36
46
 
37
47
  describe '#get_locale_resource' do
38
- it 'load the correct locale resource file' do
48
+ it 'loads the correct locale resource file' do
39
49
  stub(resources).get_resource(:locales, :de, :numbers) { 'foo' }
40
50
  resources.get_locale_resource(:de, :numbers).should == 'foo'
41
51
  end
42
52
 
53
+ it 'loads the resource only once' do
54
+ mock(resources).load_resource('locales/de/numbers.yml').once { 'foo' }
55
+
56
+ result = resources.get_locale_resource(:de, :numbers)
57
+ # second time get_resource is not called but we get the same object as before
58
+ resources.get_locale_resource(:de, :numbers).object_id.should == result.object_id
59
+ end
60
+
43
61
  it 'converts locales' do
44
62
  mock(TwitterCldr).convert_locale('zh-tw') { :'zh-Hant' }
45
63
  mock(resources).get_resource(:locales, :'zh-Hant', :numbers) { 'foo' }
@@ -48,4 +66,10 @@ describe Resources do
48
66
  end
49
67
  end
50
68
 
69
+ def stub_resource_file(resource_path, content)
70
+ file_path = File.join(TwitterCldr::RESOURCES_DIR, resource_path)
71
+ stub(File).read(file_path) { content }
72
+ stub(File).file?(file_path) { true }
73
+ end
74
+
51
75
  end
@@ -147,6 +147,23 @@ describe Base do
147
147
  end
148
148
  end
149
149
 
150
+ describe "#expand" do
151
+ it "leaves a normal hash alone" do
152
+ hash = { :twitter => { :is => "cool" } }
153
+ @base.send(:expand, hash, hash).should == hash
154
+ end
155
+
156
+ it "expands a single symbol path" do
157
+ hash = { :twitter => { :is => :'adjective.positive' }, :adjective => { :positive => "cool" } }
158
+ @base.send(:expand, hash, hash).should == { :twitter => { :is => "cool" }, :adjective => { :positive => "cool" } }
159
+ end
160
+
161
+ it "expands nested symbol paths" do
162
+ hash = { :twitter => { :is => :'adjective.positive' }, :adjective => { :positive => :'adjective.default', :default => "awesome" } }
163
+ @base.send(:expand, hash, hash).should == { :twitter => { :is => "awesome" }, :adjective => { :positive => "awesome", :default => "awesome" } }
164
+ end
165
+ end
166
+
150
167
  describe "#traverse" do
151
168
  before(:each) do
152
169
  @tree = { :admiral => { :captain => { :commander => { :lieutenant => "Found Me!" } } } }
@@ -29,7 +29,7 @@ describe TwitterCldr do
29
29
  locales = TwitterCldr.supported_locales
30
30
  locales.should include(:es)
31
31
  locales.should include(:zh)
32
- locales.should include(:no)
32
+ locales.should include(:nb)
33
33
  locales.should include(:ja)
34
34
  end
35
35