rs_russian 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|