rs_russian 0.7.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 +7 -0
- data/.gitignore +5 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/CHANGELOG +132 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +48 -0
- data/LICENSE +20 -0
- data/README.textile +268 -0
- data/Rakefile +12 -0
- data/TODO +4 -0
- data/lib/rs_russian.rb +1 -0
- data/lib/russian/action_view_ext/helpers/date_helper.rb +118 -0
- data/lib/russian/active_model_ext/custom_error_message.rb +70 -0
- data/lib/russian/locale/actionview.yml +212 -0
- data/lib/russian/locale/activemodel.yml +50 -0
- data/lib/russian/locale/activerecord.yml +95 -0
- data/lib/russian/locale/activesupport.yml +16 -0
- data/lib/russian/locale/datetime.rb +39 -0
- data/lib/russian/locale/datetime.yml +50 -0
- data/lib/russian/locale/pluralization.rb +28 -0
- data/lib/russian/locale/transliterator.rb +17 -0
- data/lib/russian/russian_rails.rb +8 -0
- data/lib/russian/transliteration.rb +64 -0
- data/lib/russian/version.rb +9 -0
- data/lib/russian.rb +121 -0
- data/russian.gemspec +33 -0
- data/spec/fixtures/en.yml +4 -0
- data/spec/fixtures/ru.yml +4 -0
- data/spec/i18n/locale/datetime_spec.rb +120 -0
- data/spec/i18n/locale/pluralization_spec.rb +28 -0
- data/spec/locale_spec.rb +47 -0
- data/spec/russian_spec.rb +133 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/transliteration_spec.rb +51 -0
- metadata +173 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# Правило плюрализации для русского языка, взято из CLDR, http://unicode.org/cldr/
|
4
|
+
#
|
5
|
+
# Russian language pluralization rules, taken from CLDR project, http://unicode.org/cldr/
|
6
|
+
#
|
7
|
+
# one -> n mod 10 is 1 and n mod 100 is not 11;
|
8
|
+
# few -> n mod 10 in 2..4 and n mod 100 not in 12..14;
|
9
|
+
# many -> n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14;
|
10
|
+
# other -> everything else
|
11
|
+
#
|
12
|
+
# Пример
|
13
|
+
#
|
14
|
+
# :one = 1, 21, 31, 41, 51, 61...
|
15
|
+
# :few = 2-4, 22-24, 32-34...
|
16
|
+
# :many = 0, 5-20, 25-30, 35-40...
|
17
|
+
# :other = 1.31, 2.31, 5.31...
|
18
|
+
{
|
19
|
+
:ru => {
|
20
|
+
:'i18n' => {
|
21
|
+
:plural => {
|
22
|
+
:rule => lambda { |n|
|
23
|
+
n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# I18n transliteration delegates to Russian::Transliteration (we're unable
|
4
|
+
# to use common I18n transliteration tables with Russian)
|
5
|
+
#
|
6
|
+
# Правило транслитерации для I18n использует Russian::Transliteration
|
7
|
+
# (использовать обычный механизм и таблицу транслитерации I18n с
|
8
|
+
# русским языком не получится)
|
9
|
+
{
|
10
|
+
:ru => {
|
11
|
+
:i18n => {
|
12
|
+
:transliterate => {
|
13
|
+
:rule => lambda { |str| Russian.transliterate(str) }
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Russian
|
4
|
+
# Russian transliteration
|
5
|
+
#
|
6
|
+
# Транслитерация для букв русского алфавита
|
7
|
+
module Transliteration
|
8
|
+
extend self
|
9
|
+
|
10
|
+
# Transliteration heavily based on rutils gem by Julian "julik" Tarkhanov and Co.
|
11
|
+
# <http://rutils.rubyforge.org/>
|
12
|
+
# Cleaned up and optimized.
|
13
|
+
|
14
|
+
LOWER_SINGLE = {
|
15
|
+
"і"=>"i","ґ"=>"g","ё"=>"yo","№"=>"#","є"=>"e",
|
16
|
+
"ї"=>"yi","а"=>"a","б"=>"b",
|
17
|
+
"в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh",
|
18
|
+
"з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l",
|
19
|
+
"м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
|
20
|
+
"с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h",
|
21
|
+
"ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"'",
|
22
|
+
"ы"=>"y","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya",
|
23
|
+
}
|
24
|
+
LOWER_MULTI = {
|
25
|
+
"ье"=>"ie",
|
26
|
+
"ьё"=>"ie",
|
27
|
+
}
|
28
|
+
|
29
|
+
UPPER_SINGLE = {
|
30
|
+
"Ґ"=>"G","Ё"=>"YO","Є"=>"E","Ї"=>"YI","І"=>"I",
|
31
|
+
"А"=>"A","Б"=>"B","В"=>"V","Г"=>"G",
|
32
|
+
"Д"=>"D","Е"=>"E","Ж"=>"ZH","З"=>"Z","И"=>"I",
|
33
|
+
"Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N",
|
34
|
+
"О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T",
|
35
|
+
"У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"TS","Ч"=>"CH",
|
36
|
+
"Ш"=>"SH","Щ"=>"SCH","Ъ"=>"'","Ы"=>"Y","Ь"=>"",
|
37
|
+
"Э"=>"E","Ю"=>"YU","Я"=>"YA",
|
38
|
+
}
|
39
|
+
UPPER_MULTI = {
|
40
|
+
"ЬЕ"=>"IE",
|
41
|
+
"ЬЁ"=>"IE",
|
42
|
+
}
|
43
|
+
|
44
|
+
LOWER = (LOWER_SINGLE.merge(LOWER_MULTI)).freeze
|
45
|
+
UPPER = (UPPER_SINGLE.merge(UPPER_MULTI)).freeze
|
46
|
+
MULTI_KEYS = (LOWER_MULTI.merge(UPPER_MULTI)).keys.sort_by {|s| s.length}.reverse.freeze
|
47
|
+
SCAN_REGEX = %r{#{MULTI_KEYS.join '|'}|\w|.}.freeze
|
48
|
+
|
49
|
+
# Transliterate a string with russian characters
|
50
|
+
#
|
51
|
+
# Возвращает строку, в которой все буквы русского алфавита заменены на похожую по звучанию латиницу
|
52
|
+
def transliterate(str)
|
53
|
+
chars = str.scan(SCAN_REGEX)
|
54
|
+
|
55
|
+
result = ''
|
56
|
+
|
57
|
+
chars.each_with_index do |char, index|
|
58
|
+
result << ( LOWER[char] || ( ( upper = UPPER[char] ) ? LOWER[chars[index+1]] ? upper.capitalize : upper : char ) )
|
59
|
+
end
|
60
|
+
|
61
|
+
result
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/russian.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
$KCODE = 'u' if RUBY_VERSION < "1.9"
|
4
|
+
|
5
|
+
require 'i18n'
|
6
|
+
|
7
|
+
$:.push File.join(File.dirname(__FILE__), 'russian')
|
8
|
+
require 'russian_rails'
|
9
|
+
|
10
|
+
if RUBY_ENGINE == "jruby"
|
11
|
+
require 'unicode_utils/upcase'
|
12
|
+
else
|
13
|
+
require 'unicode'
|
14
|
+
end
|
15
|
+
|
16
|
+
module Russian
|
17
|
+
extend self
|
18
|
+
|
19
|
+
autoload :Transliteration, 'transliteration'
|
20
|
+
|
21
|
+
# Russian locale
|
22
|
+
LOCALE = :'ru'
|
23
|
+
|
24
|
+
# Russian locale
|
25
|
+
def locale
|
26
|
+
LOCALE
|
27
|
+
end
|
28
|
+
|
29
|
+
# Regexp machers for context-based russian month names and day names translation
|
30
|
+
LOCALIZE_ABBR_MONTH_NAMES_MATCH = /(%[-_0^#:]*(\d+)*[EO]?d|%[-_0^#:]*(\d+)*[EO]?e)(.*)(%b)/
|
31
|
+
LOCALIZE_MONTH_NAMES_MATCH = /(%[-_0^#:]*(\d+)*[EO]?d|%[-_0^#:]*(\d+)*[EO]?e)(.*)(%B)/
|
32
|
+
LOCALIZE_STANDALONE_ABBR_DAY_NAMES_MATCH = /^%a/
|
33
|
+
LOCALIZE_STANDALONE_DAY_NAMES_MATCH = /^%A/
|
34
|
+
|
35
|
+
# Init Russian i18n: load all translations shipped with library.
|
36
|
+
def init_i18n
|
37
|
+
I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
|
38
|
+
I18n::Backend::Simple.send(:include, I18n::Backend::Transliterator)
|
39
|
+
|
40
|
+
I18n.load_path.unshift(*locale_files)
|
41
|
+
|
42
|
+
I18n.reload!
|
43
|
+
end
|
44
|
+
|
45
|
+
# See I18n::translate
|
46
|
+
def translate(key, options = {})
|
47
|
+
I18n.translate(key, options.merge({ :locale => LOCALE }))
|
48
|
+
end
|
49
|
+
alias :t :translate
|
50
|
+
|
51
|
+
# See I18n::localize
|
52
|
+
def localize(object, options = {})
|
53
|
+
I18n.localize(object, options.merge({ :locale => LOCALE }))
|
54
|
+
end
|
55
|
+
alias :l :localize
|
56
|
+
|
57
|
+
# strftime() proxy with Russian localization
|
58
|
+
def strftime(object, format = :default)
|
59
|
+
localize(object, { :format => check_strftime_format(object, format) })
|
60
|
+
end
|
61
|
+
|
62
|
+
# Simple pluralization proxy
|
63
|
+
#
|
64
|
+
# Usage:
|
65
|
+
# Russian.pluralize(1, "вещь", "вещи", "вещей")
|
66
|
+
# Russian.pluralize(3.14, "вещь", "вещи", "вещей", "вещи")
|
67
|
+
# Russina.pluralize(5, "Произошла %n ошибка", "Произошло %n ошибки", "Произошло %n ошибок")
|
68
|
+
def pluralize(n, *variants)
|
69
|
+
raise ArgumentError, "Must have a Numeric as a first parameter" unless n.is_a?(Numeric)
|
70
|
+
raise ArgumentError, "Must have at least 3 variants for pluralization" if variants.size < 3
|
71
|
+
raise ArgumentError, "Must have at least 4 variants for pluralization" if (variants.size < 4 && n != n.round)
|
72
|
+
variants_hash = pluralization_variants_to_hash(n, *variants)
|
73
|
+
I18n.backend.send(:pluralize, LOCALE, variants_hash, n)
|
74
|
+
end
|
75
|
+
alias :p :pluralize
|
76
|
+
|
77
|
+
# Transliteration for russian language
|
78
|
+
#
|
79
|
+
# Usage:
|
80
|
+
# Russian.translit("рубин")
|
81
|
+
# Russian.transliterate("рубин")
|
82
|
+
def transliterate(str)
|
83
|
+
Russian::Transliteration.transliterate(str)
|
84
|
+
end
|
85
|
+
alias :translit :transliterate
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def check_strftime_format(object, format)
|
90
|
+
%w(A a B b).each do |key|
|
91
|
+
if format =~ /%\^#{key}/
|
92
|
+
if RUBY_ENGINE == "jruby"
|
93
|
+
format = format.gsub("%^#{key}", UnicodeUtils.upcase(localize(object, { :format => "%#{key}" } )))
|
94
|
+
else
|
95
|
+
format = format.gsub("%^#{key}", Unicode::upcase(localize(object, { :format => "%#{key}" } )))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
format
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns all locale files shipped with library
|
104
|
+
def locale_files
|
105
|
+
Dir[File.join(File.dirname(__FILE__), "russian", "locale", "**/*")]
|
106
|
+
end
|
107
|
+
|
108
|
+
# Converts an array of pluralization variants to a Hash that can be used
|
109
|
+
# with I18n pluralization.
|
110
|
+
def pluralization_variants_to_hash(n, *variants)
|
111
|
+
variants.map!{ |variant| variant.gsub '%n', n.to_s }
|
112
|
+
{
|
113
|
+
:one => variants[0],
|
114
|
+
:few => variants[1],
|
115
|
+
:many => variants[2],
|
116
|
+
:other => variants[3]
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
Russian.init_i18n
|
data/russian.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$: << File.expand_path('../lib', __FILE__)
|
4
|
+
require 'russian/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rs_russian"
|
8
|
+
spec.version = Russian::VERSION::STRING
|
9
|
+
spec.authors = ["glebtv", "Yaroslav Markin"]
|
10
|
+
spec.email = ["glebtv@gmail.com", "yaroslav@markin.net"]
|
11
|
+
spec.description = %q{Russian language support for Ruby and Rails}
|
12
|
+
spec.summary = %q{Russian language support for Ruby and Rails}
|
13
|
+
spec.homepage = "https://github.com/rs-pro/russian"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'i18n', '~> 0.6.0'
|
22
|
+
|
23
|
+
unless RUBY_PLATFORM =~ /java/
|
24
|
+
spec.add_dependency 'unicode', '~> 0.4.4'
|
25
|
+
else
|
26
|
+
spec.add_dependency 'unicode_utils', '~> 1.4.0'
|
27
|
+
end
|
28
|
+
|
29
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
30
|
+
spec.add_development_dependency 'rake'
|
31
|
+
spec.add_development_dependency 'rspec'
|
32
|
+
spec.add_development_dependency 'activesupport', '>= 3.0.0'
|
33
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
4
|
+
|
5
|
+
describe I18n, "Russian Date/Time localization" do
|
6
|
+
before(:all) do
|
7
|
+
Russian.init_i18n
|
8
|
+
@date = Date.parse("1985-12-01")
|
9
|
+
@time = Time.local(1985, 12, 01, 16, 05)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "with date formats" do
|
13
|
+
it "should use default format" do
|
14
|
+
l(@date).should == "01.12.1985"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should use short format" do
|
18
|
+
l(@date, :format => :short).should == "01 дек"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should use long format" do
|
22
|
+
l(@date, :format => :long).should == "01 декабря 1985"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "with date day names" do
|
27
|
+
it "should use day names" do
|
28
|
+
l(@date, :format => "%d %B (%A)").should == "01 декабря (воскресенье)"
|
29
|
+
l(@date, :format => "%d %B %Y года было %A").should == "01 декабря 1985 года было воскресенье"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should use standalone day names" do
|
33
|
+
l(@date, :format => "%A").should == "Воскресенье"
|
34
|
+
l(@date, :format => "%A, %d %B").should == "Воскресенье, 01 декабря"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should use abbreviated day names" do
|
38
|
+
l(@date, :format => "%a").should == "Вс"
|
39
|
+
l(@date, :format => "%a, %d %b %Y").should == "Вс, 01 дек 1985"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should use uppercased day names" do
|
43
|
+
Russian::strftime(@date, "%^a").should == "ВС"
|
44
|
+
Russian::strftime(@date, "%^A").should == "ВОСКРЕСЕНЬЕ"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "with month names" do
|
49
|
+
it "should use month names" do
|
50
|
+
l(@date, :format => "%d %B").should == "01 декабря"
|
51
|
+
l(@date, :format => "%-d %B").should == "1 декабря"
|
52
|
+
|
53
|
+
if RUBY_VERSION > "1.9.2"
|
54
|
+
l(@date, :format => "%1d %B").should == "1 декабря"
|
55
|
+
l(@date, :format => "%2d %B").should == "01 декабря"
|
56
|
+
l(@date, :format => "%10d %B").should == "0000000001 декабря"
|
57
|
+
l(@date, :format => "%-e %B %Y").should == "1 декабря 1985"
|
58
|
+
l(@date, :format => "%_3d %B %Y").should == " 1 декабря 1985"
|
59
|
+
l(@date, :format => "%3_d %B %Y").should == "%3_d Декабрь 1985"
|
60
|
+
end
|
61
|
+
|
62
|
+
l(@date, :format => "%e %B %Y").should == " 1 декабря 1985"
|
63
|
+
l(@date, :format => "<b>%d</b> %B").should == "<b>01</b> декабря"
|
64
|
+
l(@date, :format => "<strong>%e</strong> %B %Y").should == "<strong> 1</strong> декабря 1985"
|
65
|
+
l(@date, :format => "А было тогда %eе число %B %Y").should == "А было тогда 1е число декабря 1985"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should use standalone month names" do
|
69
|
+
l(@date, :format => "%B").should == "Декабрь"
|
70
|
+
l(@date, :format => "%B %Y").should == "Декабрь 1985"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should use abbreviated month names" do
|
74
|
+
@date = Date.parse("1985-03-01")
|
75
|
+
l(@date, :format => "%d %b").should == "01 мар"
|
76
|
+
l(@date, :format => "%e %B %Y").should == " 1 марта 1985"
|
77
|
+
l(@date, :format => "<b>%d</b> %B").should == "<b>01</b> марта"
|
78
|
+
l(@date, :format => "<strong>%e</strong> %B %Y").should == "<strong> 1</strong> марта 1985"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should use uppercased month names" do
|
82
|
+
Russian::strftime(@date, "%^b").should == "ДЕК"
|
83
|
+
Russian::strftime(@date, "%^B").should == "ДЕКАБРЬ"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should use standalone abbreviated month names" do
|
87
|
+
@date = Date.parse("1985-03-01")
|
88
|
+
l(@date, :format => "%b").should == "мар"
|
89
|
+
l(@date, :format => "%b %Y").should == "мар 1985"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should define default date components order: day, month, year" do
|
94
|
+
I18n.backend.translate(Russian.locale, :"date.order").should == [:day, :month, :year]
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "with time formats" do
|
98
|
+
it "should use default format" do
|
99
|
+
l(@time).should match(/^Вс, 01 дек 1985, 16:05:00/)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should use short format" do
|
103
|
+
l(@time, :format => :short).should == "01 дек, 16:05"
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should use long format" do
|
107
|
+
l(@time, :format => :long).should == "01 декабря 1985, 16:05"
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should define am and pm" do
|
111
|
+
I18n.backend.translate(Russian.locale, :"time.am").should_not be_nil
|
112
|
+
I18n.backend.translate(Russian.locale, :"time.pm").should_not be_nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
protected
|
117
|
+
def l(object, options = {})
|
118
|
+
I18n.l(object, options.merge( { :locale => Russian.locale }))
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
4
|
+
|
5
|
+
describe I18n, "Russian pluralization" do
|
6
|
+
before(:each) do
|
7
|
+
@hash = {}
|
8
|
+
%w(one few many other).each do |key|
|
9
|
+
@hash[key.to_sym] = key
|
10
|
+
end
|
11
|
+
@backend = I18n.backend
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should pluralize correctly" do
|
15
|
+
@backend.send(:pluralize, :'ru', @hash, 1).should == 'one'
|
16
|
+
@backend.send(:pluralize, :'ru', @hash, 2).should == 'few'
|
17
|
+
@backend.send(:pluralize, :'ru', @hash, 3).should == 'few'
|
18
|
+
@backend.send(:pluralize, :'ru', @hash, 5).should == 'many'
|
19
|
+
@backend.send(:pluralize, :'ru', @hash, 10).should == 'many'
|
20
|
+
@backend.send(:pluralize, :'ru', @hash, 11).should == 'many'
|
21
|
+
@backend.send(:pluralize, :'ru', @hash, 21).should == 'one'
|
22
|
+
@backend.send(:pluralize, :'ru', @hash, 29).should == 'many'
|
23
|
+
@backend.send(:pluralize, :'ru', @hash, 131).should == 'one'
|
24
|
+
@backend.send(:pluralize, :'ru', @hash, 1.31).should == 'other'
|
25
|
+
@backend.send(:pluralize, :'ru', @hash, 2.31).should == 'other'
|
26
|
+
@backend.send(:pluralize, :'ru', @hash, 3.31).should == 'other'
|
27
|
+
end
|
28
|
+
end
|
data/spec/locale_spec.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
4
|
+
|
5
|
+
describe Russian, "loading locales" do
|
6
|
+
before(:all) do
|
7
|
+
Russian.init_i18n
|
8
|
+
end
|
9
|
+
|
10
|
+
%w(
|
11
|
+
date.formats.default
|
12
|
+
date.formats.short
|
13
|
+
date.formats.long
|
14
|
+
date.day_names
|
15
|
+
date.standalone_day_names
|
16
|
+
date.abbr_day_names
|
17
|
+
date.month_names
|
18
|
+
date.standalone_month_names
|
19
|
+
date.abbr_month_names
|
20
|
+
date.standalone_abbr_month_names
|
21
|
+
date.order
|
22
|
+
|
23
|
+
time.formats.default
|
24
|
+
time.formats.short
|
25
|
+
time.formats.long
|
26
|
+
time.am
|
27
|
+
time.pm
|
28
|
+
).each do |key|
|
29
|
+
it "should define '#{key}' in datetime translations" do
|
30
|
+
lookup(key).should_not be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should load pluralization rules" do
|
35
|
+
lookup(:'i18n.plural.rule').should_not be_nil
|
36
|
+
lookup(:'i18n.plural.rule').is_a?(Proc).should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should load transliteration rule" do
|
40
|
+
lookup(:'i18n.transliterate.rule').should_not be_nil
|
41
|
+
lookup(:'i18n.transliterate.rule').is_a?(Proc).should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
def lookup(*args)
|
45
|
+
I18n.backend.send(:lookup, Russian.locale, *args)
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
4
|
+
|
5
|
+
describe Russian do
|
6
|
+
describe "with locale" do
|
7
|
+
it "should define :'ru' LOCALE" do
|
8
|
+
Russian::LOCALE.should == :'ru'
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should provide 'locale' proxy" do
|
12
|
+
Russian.locale.should == Russian::LOCALE
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "during i18n initialization" do
|
17
|
+
after(:each) do
|
18
|
+
I18n.load_path = []
|
19
|
+
Russian.init_i18n
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should keep existing translations while switching backends" do
|
23
|
+
I18n.load_path << File.join(File.dirname(__FILE__), 'fixtures', 'en.yml')
|
24
|
+
Russian.init_i18n
|
25
|
+
I18n.t(:foo, :locale => :'en').should == "bar"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should keep existing :ru translations while switching backends" do
|
29
|
+
I18n.load_path << File.join(File.dirname(__FILE__), 'fixtures', 'ru.yml')
|
30
|
+
Russian.init_i18n
|
31
|
+
I18n.t(:'date.formats.default', :locale => :'ru').should == "override"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should NOT set default locale to Russian locale" do
|
35
|
+
locale = I18n.default_locale
|
36
|
+
Russian.init_i18n
|
37
|
+
I18n.default_locale.should == locale
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "with localize proxy" do
|
42
|
+
before(:each) do
|
43
|
+
@time = mock(:time)
|
44
|
+
@options = { :format => "%d %B %Y" }
|
45
|
+
end
|
46
|
+
|
47
|
+
%w(l localize).each do |method|
|
48
|
+
it "'#{method}' should call I18n backend localize" do
|
49
|
+
I18n.should_receive(:localize).with(@time, @options.merge({ :locale => Russian.locale }))
|
50
|
+
Russian.send(method, @time, @options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "with translate proxy" do
|
56
|
+
before(:all) do
|
57
|
+
@object = :bar
|
58
|
+
@options = { :scope => :foo }
|
59
|
+
end
|
60
|
+
|
61
|
+
%w(t translate).each do |method|
|
62
|
+
it "'#{method}' should call I18n backend translate" do
|
63
|
+
I18n.should_receive(:translate).with(@object, @options.merge({ :locale => Russian.locale }))
|
64
|
+
Russian.send(method, @object, @options)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "strftime" do
|
70
|
+
before(:each) do
|
71
|
+
@time = mock(:time)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should call localize with object and format" do
|
75
|
+
format = "%d %B %Y"
|
76
|
+
Russian.should_receive(:localize).with(@time, { :format => format })
|
77
|
+
Russian.strftime(@time, format)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should call localize with object and default format when format is not specified" do
|
81
|
+
Russian.should_receive(:localize).with(@time, { :format => :default })
|
82
|
+
Russian.strftime(@time)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "with pluralization" do
|
87
|
+
%w(p pluralize).each do |method|
|
88
|
+
it "'#{method}' should pluralize with variants given" do
|
89
|
+
variants = %w(вещь вещи вещей вещи)
|
90
|
+
|
91
|
+
Russian.send(method, 1, *variants).should == "вещь"
|
92
|
+
Russian.send(method, 2, *variants).should == 'вещи'
|
93
|
+
Russian.send(method, 3, *variants).should == 'вещи'
|
94
|
+
Russian.send(method, 5, *variants).should == 'вещей'
|
95
|
+
Russian.send(method, 10, *variants).should == 'вещей'
|
96
|
+
Russian.send(method, 21, *variants).should == 'вещь'
|
97
|
+
Russian.send(method, 29, *variants).should == 'вещей'
|
98
|
+
Russian.send(method, 129, *variants).should == 'вещей'
|
99
|
+
Russian.send(method, 131, *variants).should == 'вещь'
|
100
|
+
Russian.send(method, 3.14, *variants).should == 'вещи'
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should pluralize with %n as number" do
|
104
|
+
variants = ['Произошла %n ошибка', 'Произошло %n ошибки', 'Произошло %n ошибок', 'Произошло %n ошибки']
|
105
|
+
|
106
|
+
Russian.send(method, 1, *variants).should == 'Произошла 1 ошибка'
|
107
|
+
Russian.send(method, 2, *variants).should == 'Произошло 2 ошибки'
|
108
|
+
Russian.send(method, 3, *variants).should == 'Произошло 3 ошибки'
|
109
|
+
Russian.send(method, 5, *variants).should == 'Произошло 5 ошибок'
|
110
|
+
Russian.send(method, 10, *variants).should == 'Произошло 10 ошибок'
|
111
|
+
Russian.send(method, 21, *variants).should == 'Произошла 21 ошибка'
|
112
|
+
Russian.send(method, 29, *variants).should == 'Произошло 29 ошибок'
|
113
|
+
Russian.send(method, 129, *variants).should == 'Произошло 129 ошибок'
|
114
|
+
Russian.send(method, 131, *variants).should == 'Произошла 131 ошибка'
|
115
|
+
Russian.send(method, 3.14, *variants).should == 'Произошло 3.14 ошибки'
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should raise an exception when first parameter is not a number" do
|
119
|
+
lambda { Russian.send(method, nil, "вещь", "вещи", "вещей") }.should raise_error(ArgumentError)
|
120
|
+
lambda { Russian.send(method, "вещь", "вещь", "вещи", "вещей") }.should raise_error(ArgumentError)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should raise an exception when there are not enough variants" do
|
124
|
+
lambda { Russian.send(method, 1) }.should raise_error(ArgumentError)
|
125
|
+
lambda { Russian.send(method, 1, "вещь") }.should raise_error(ArgumentError)
|
126
|
+
lambda { Russian.send(method, 1, "вещь", "вещи") }.should raise_error(ArgumentError)
|
127
|
+
lambda { Russian.send(method, 1, "вещь", "вещи", "вещей") }.should_not raise_error(ArgumentError)
|
128
|
+
lambda { Russian.send(method, 3.14, "вещь", "вещи", "вещей") }.should raise_error(ArgumentError)
|
129
|
+
lambda { Russian.send(method, 3.14, "вещь", "вещи", "вещей", "вещи") }.should_not raise_error(ArgumentError)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|