tr8n 3.2.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. data/Gemfile.lock +3 -1
  2. data/app/assets/javascripts/tr8n/tr8n-compiled.js +336 -0
  3. data/app/assets/stylesheets/tr8n/admin.css.scss +23 -0
  4. data/app/assets/stylesheets/tr8n/components.css.scss +23 -0
  5. data/app/assets/stylesheets/tr8n/keyboard_1_49.css +271 -0
  6. data/app/assets/stylesheets/tr8n/layout.css.scss +23 -0
  7. data/app/assets/stylesheets/tr8n/tr8n.css.scss +1 -1
  8. data/app/controllers/tr8n/api/v1/base_controller.rb +6 -0
  9. data/app/controllers/tr8n/api/v1/language_controller.rb +7 -10
  10. data/app/controllers/tr8n/api/v1/translation_controller.rb +0 -1
  11. data/app/javascript/compile.rb +37 -0
  12. data/app/javascript/compile.sh +1 -0
  13. data/app/javascript/compressors/google/COPYING +202 -0
  14. data/app/javascript/compressors/google/README +292 -0
  15. data/app/javascript/compressors/google/compiler.jar +0 -0
  16. data/app/javascript/config.yml +66 -0
  17. data/app/javascript/src/base.js +35 -0
  18. data/app/javascript/src/effects.js +67 -0
  19. data/app/javascript/src/ext/inflector.js +309 -0
  20. data/app/{assets/javascripts/tr8n → javascript/src/ext}/jsDraw2D.js +0 -0
  21. data/app/{assets/javascripts/tr8n → javascript/src/ext}/keyboard_1_36.js +0 -0
  22. data/app/{assets/javascripts/tr8n → javascript/src/ext}/keyboard_1_44.js +0 -0
  23. data/app/javascript/src/ext/keyboard_1_49.js +1796 -0
  24. data/app/javascript/src/ext/md5.js +209 -0
  25. data/app/{assets/javascripts/tr8n → javascript/src/ext}/shortcut.js +0 -0
  26. data/app/javascript/src/init.js +47 -0
  27. data/app/javascript/src/language.js +38 -0
  28. data/app/javascript/src/logger.js +203 -0
  29. data/app/{assets/javascripts/tr8n/tr8n_prototype_effects.js → javascript/src/prototype/effects.js} +5 -5
  30. data/app/javascript/src/proxy.js +254 -0
  31. data/app/javascript/src/rules/date_rule.js +37 -0
  32. data/app/javascript/src/rules/gender_list_rule.js +37 -0
  33. data/app/javascript/src/rules/gender_rule.js +87 -0
  34. data/app/javascript/src/rules/language_rule.js +55 -0
  35. data/app/javascript/src/rules/list_rule.js +37 -0
  36. data/app/javascript/src/rules/numeric_rule.js +95 -0
  37. data/app/javascript/src/tml/label.js +60 -0
  38. data/app/javascript/src/tml/token.js +107 -0
  39. data/app/javascript/src/tokens/data_token.js +45 -0
  40. data/app/javascript/src/tokens/decoration_token.js +82 -0
  41. data/app/javascript/src/tokens/token.js +121 -0
  42. data/app/javascript/src/tokens/transform_token.js +106 -0
  43. data/app/javascript/src/translation_key.js +183 -0
  44. data/app/javascript/src/ui/language_case_manager.js +155 -0
  45. data/app/javascript/src/ui/language_selector.js +126 -0
  46. data/app/javascript/src/ui/lightbox.js +72 -0
  47. data/app/javascript/src/ui/translator.js +257 -0
  48. data/app/javascript/src/utils.js +286 -0
  49. data/app/models/tr8n/language_case.rb +27 -16
  50. data/app/models/tr8n/language_case_rule.rb +24 -7
  51. data/app/models/tr8n/translation_key.rb +23 -21
  52. data/app/views/tr8n/common/_scripts.html.erb +8 -10
  53. data/app/views/tr8n/language_cases/_manager_header.html.erb +3 -3
  54. data/app/views/tr8n/language_cases/manager.html.erb +2 -2
  55. data/app/views/tr8n/translations/_original_phrase.html.erb +1 -1
  56. data/lib/tr8n/extensions/action_view_extension.rb +8 -1
  57. data/lib/tr8n/keyboard_mapping.rb +101 -0
  58. data/lib/tr8n/token.rb +1 -2
  59. data/lib/tr8n/version.rb +1 -1
  60. data/spec/models/tr8n/gender_rule_spec.rb +6 -6
  61. data/spec/models/tr8n/language_case_rule_spec.rb +219 -1
  62. data/spec/models/tr8n/language_case_spec.rb +51 -1
  63. data/spec/models/tr8n/translation_key_spec.rb +256 -0
  64. data/tr8n.gemspec +2 -1
  65. metadata +129 -47
  66. data/app/assets/javascripts/tr8n/tr8n.js +0 -905
  67. data/app/assets/javascripts/tr8n/tr8n_client_sdk.js +0 -1472
@@ -23,5 +23,5 @@
23
23
 
24
24
 
25
25
  module Tr8n
26
- VERSION = "3.2.0"
26
+ VERSION = "3.2.1"
27
27
  end
@@ -51,8 +51,8 @@ describe Tr8n::GenderRule do
51
51
  male.stub!(:gender).and_return("male")
52
52
  female = mock("male")
53
53
  female.stub!(:gender).and_return("female")
54
- unknwon = mock("unknwon")
55
- unknwon.stub!(:gender).and_return("unknwon")
54
+ unknown = mock("unknown")
55
+ unknown.stub!(:gender).and_return("unknown")
56
56
 
57
57
  Tr8n::GenderRule.transform(male, "registered on").should eq("registered on")
58
58
  Tr8n::GenderRule.transform(male, "he", "she").should eq("he")
@@ -64,10 +64,10 @@ describe Tr8n::GenderRule do
64
64
  Tr8n::GenderRule.transform(female, "his", "her").should eq("her")
65
65
  Tr8n::GenderRule.transform(female, "he", "she", "he/she").should eq("she")
66
66
 
67
- Tr8n::GenderRule.transform(unknwon, "registered on").should eq("registered on")
68
- Tr8n::GenderRule.transform(unknwon, "he", "she").should eq("he/she")
69
- Tr8n::GenderRule.transform(unknwon, "his", "her").should eq("his/her")
70
- Tr8n::GenderRule.transform(unknwon, "he", "she", "he/she").should eq("he/she")
67
+ Tr8n::GenderRule.transform(unknown, "registered on").should eq("registered on")
68
+ Tr8n::GenderRule.transform(unknown, "he", "she").should eq("he/she")
69
+ Tr8n::GenderRule.transform(unknown, "his", "her").should eq("his/her")
70
+ Tr8n::GenderRule.transform(unknown, "he", "she", "he/she").should eq("he/she")
71
71
  end
72
72
  end
73
73
  end
@@ -1,5 +1,223 @@
1
1
  require File.expand_path('../../spec_helper', File.dirname(__FILE__))
2
2
 
3
3
  describe Tr8n::LanguageCaseRule do
4
-
4
+ describe "language case rule creation" do
5
+ before :all do
6
+ @user = User.create(:first_name => "Mike", :gender => "male")
7
+ @translator = Tr8n::Translator.create(:name => "Mike", :user => @user, :gender => "male")
8
+ @english = Tr8n::Language.create(:locale => "en-US", :english_name => "English")
9
+ @russian = Tr8n::Language.create(:locale => "ru", :english_name => "Russian")
10
+
11
+ @lcase_en = Tr8n::LanguageCase.create(
12
+ language: @english,
13
+ keyword: "pos",
14
+ latin_name: "Possessive",
15
+ native_name: "Possessive",
16
+ description: "Used to indicate possession (i.e., ownership). It is usually created by adding 's to the word",
17
+ application: "phrase")
18
+
19
+ @lcase_ru = Tr8n::LanguageCase.create(
20
+ language: @russian,
21
+ keyword: "pos",
22
+ latin_name: "Possessive",
23
+ native_name: "Possessive",
24
+ description: "Used to indicate possession (i.e., ownership).",
25
+ application: "words")
26
+ end
27
+
28
+ after :all do
29
+ [@user, @translator, @english, @russian,
30
+ @lcase_en, @lcase_ru].each do |obj|
31
+ obj.destroy
32
+ end
33
+ end
34
+
35
+ describe "evaluating simple rules without genders" do
36
+ it "should result in correct substitution" do
37
+ lcrule = Tr8n::LanguageCaseRule.create(
38
+ :language => @english,
39
+ :language_case => @lcase_en,
40
+ :definition => {
41
+ part1: "ends_in",
42
+ value1: "s",
43
+ operation: "append",
44
+ operation_value: "'"
45
+ })
46
+
47
+ lcrule.should be_a(Tr8n::LanguageCaseRule)
48
+
49
+ lcrule.definition[:part1].should eq("ends_in")
50
+ lcrule.definition["part1"].should eq("ends_in")
51
+
52
+ lcrule.evaluate_part("Michael", 1).should be_false
53
+ lcrule.evaluate(nil, "Michael").should be_false
54
+
55
+ lcrule.evaluate_part("Anna", 1).should be_false
56
+ lcrule.evaluate(nil, "Anna").should be_false
57
+
58
+ lcrule.evaluate_part("friends", 1).should be_true
59
+ lcrule.evaluate(nil, "friends").should be_true
60
+ lcrule.apply("friends").should eq("friends'")
61
+
62
+
63
+ lcrule = Tr8n::LanguageCaseRule.create(
64
+ :language => @english,
65
+ :language_case => @lcase_en,
66
+ :definition => {
67
+ part1: "does_not_end_in",
68
+ value1: "s", operation: "append",
69
+ operation_value: "'s"
70
+ })
71
+
72
+ lcrule.evaluate(nil, "Michael").should be_true
73
+ lcrule.apply("Michael").should eq("Michael's")
74
+
75
+ lcrule.evaluate(nil, "Anna").should be_true
76
+ lcrule.apply("Anna").should eq("Anna's")
77
+
78
+ lcrule.evaluate(nil, "friends").should be_false
79
+
80
+ lcrule = Tr8n::LanguageCaseRule.create(
81
+ :language => @english,
82
+ :language_case => @lcase_en,
83
+ :definition => {
84
+ part1: "is",
85
+ value1: "1",
86
+ operation: "replace",
87
+ operation_value: "first",
88
+ })
89
+
90
+ lcrule.evaluate(nil, "2").should be_false
91
+ lcrule.evaluate(nil, "1").should be_true
92
+ lcrule.apply("1").should eq("first")
93
+
94
+ lcrule = Tr8n::LanguageCaseRule.create(
95
+ :language => @english,
96
+ :language_case => @lcase_en,
97
+ :definition => {
98
+ part1: "ends_in",
99
+ value1: "0,4,5,6,7,8,9,11,12,13",
100
+ operation: "append",
101
+ operation_value: "th",
102
+ })
103
+
104
+ lcrule.evaluate(nil, "4").should be_true
105
+ lcrule.apply("4").should eq("4th")
106
+
107
+ lcrule.evaluate(nil, "7").should be_true
108
+ lcrule.apply("7").should eq("7th")
109
+
110
+ end
111
+ end
112
+
113
+ describe "evaluating simple rules with genders" do
114
+ it "should result in correct substitution" do
115
+ lcrule1 = Tr8n::LanguageCaseRule.create(
116
+ :language => @russian,
117
+ :language_case => @lcase_ru,
118
+ :definition => {
119
+ gender: "female",
120
+ part1: "is",
121
+ value1: "1",
122
+ operation: "replace",
123
+ operation_value: "pervaya",
124
+ })
125
+
126
+ lcrule2 = Tr8n::LanguageCaseRule.create(
127
+ :language => @russian,
128
+ :language_case => @lcase_ru,
129
+ :definition => {
130
+ gender: "male",
131
+ part1: "is",
132
+ value1: "1",
133
+ operation: "replace",
134
+ operation_value: "pervii",
135
+ })
136
+
137
+ anna = mock("female")
138
+ anna.stub!(:to_s).and_return("Anna")
139
+ anna.stub!(:gender).and_return("female")
140
+
141
+ michael = mock("male")
142
+ michael.stub!(:to_s).and_return("Michael")
143
+ michael.stub!(:gender).and_return("male")
144
+
145
+ lcrule1.evaluate(michael, "1").should be_false
146
+ lcrule1.evaluate(anna, "1").should be_true
147
+ lcrule1.apply("1").should eq("pervaya")
148
+
149
+ lcrule2.evaluate(anna, "1").should be_false
150
+ lcrule2.evaluate(michael, "1").should be_true
151
+ lcrule2.apply("1").should eq("pervii")
152
+ end
153
+ end
154
+
155
+ describe "applying rules" do
156
+ describe "when using replace" do
157
+ it "it should correctly replace values" do
158
+ lcrule = Tr8n::LanguageCaseRule.create(
159
+ :language => @english,
160
+ :language_case => @lcase_ru,
161
+ :definition => {
162
+ part1: "is",
163
+ value1: "1",
164
+ operation: "replace",
165
+ operation_value: "1st",
166
+ })
167
+
168
+ lcrule.evaluate(nil, "1").should be_true
169
+ lcrule.apply("1").should eq("1st")
170
+ end
171
+ end
172
+
173
+ describe "when using append" do
174
+ it "it should correctly append values" do
175
+ lcrule = Tr8n::LanguageCaseRule.create(
176
+ :language => @english,
177
+ :language_case => @lcase_ru,
178
+ :definition => {
179
+ part1: "is",
180
+ value1: "1",
181
+ operation: "append",
182
+ operation_value: "st",
183
+ })
184
+
185
+ lcrule.evaluate(nil, "1").should be_true
186
+ lcrule.apply("1").should eq("1st")
187
+ end
188
+ end
189
+
190
+ describe "when using prepand" do
191
+ it "it should correctly prepand values" do
192
+ lcrule = Tr8n::LanguageCaseRule.create(
193
+ :language => @english,
194
+ :language_case => @lcase_ru,
195
+ :definition => {
196
+ part1: "starts_with",
197
+ value1: "q,w,r,t,p,s,d,f,g,j,k,h,l,z,x,c,v,b,n,m",
198
+ operation: "prepand",
199
+ operation_value: "a ",
200
+ })
201
+
202
+ lcrule.evaluate(nil, "car").should be_true
203
+ lcrule.apply("car").should eq("a car")
204
+
205
+ lcrule = Tr8n::LanguageCaseRule.create(
206
+ :language => @english,
207
+ :language_case => @lcase_ru,
208
+ :definition => {
209
+ part1: "starts_with",
210
+ value1: "e,u,i,o,a",
211
+ operation: "prepand",
212
+ operation_value: "an ",
213
+ })
214
+
215
+ lcrule.evaluate(nil, "apple").should be_true
216
+ lcrule.apply("apple").should eq("an apple")
217
+ end
218
+ end
219
+
220
+ end
221
+
222
+ end
5
223
  end
@@ -1,5 +1,55 @@
1
1
  require File.expand_path('../../spec_helper', File.dirname(__FILE__))
2
2
 
3
3
  describe Tr8n::LanguageCase do
4
-
4
+ describe "language case creation" do
5
+ before :all do
6
+ @user = User.create(:first_name => "Mike", :gender => "male")
7
+ @translator = Tr8n::Translator.create!(:name => "Mike", :user => @user, :gender => "male")
8
+ @english = Tr8n::Language.create!(:locale => "en-US", :english_name => "English")
9
+ @russian = Tr8n::Language.create!(:locale => "ru", :english_name => "Russian")
10
+ end
11
+
12
+ after :all do
13
+ [@user, @translator, @english, @russian].each do |obj|
14
+ obj.destroy
15
+ end
16
+ end
17
+
18
+ describe "registering cache key" do
19
+ it "should contain language and keyword" do
20
+ lcase = Tr8n::LanguageCase.create(
21
+ language: @english,
22
+ keyword: "pos",
23
+ latin_name: "Possessive",
24
+ native_name: "Possessive",
25
+ description: "Used to indicate possession (i.e., ownership). It is usually created by adding 's to the word",
26
+ application: "phrase")
27
+
28
+ lcase.cache_key.should eq("language_case_en-US_pos")
29
+
30
+ Tr8n::LanguageCase.by_keyword("pos", @english).should eq(lcase)
31
+ end
32
+ end
33
+
34
+ describe "apply" do
35
+ it "should substitute the tokens with appropriate case" do
36
+ lcase = Tr8n::LanguageCase.create(
37
+ language: @english,
38
+ keyword: "pos",
39
+ latin_name: "Possessive",
40
+ native_name: "Possessive",
41
+ description: "Used to indicate possession (i.e., ownership). It is usually created by adding 's to the word",
42
+ application: "phrase")
43
+
44
+ lcase.add_rule({multipart: false, gender: "none", part1: "ends_in", value1: "s", operation: "append", operation_value: "'"})
45
+ lcase.add_rule({multipart: false, gender: "none", part1: "does_not_end_in", value1: "s", operation: "append", operation_value: "'s"})
46
+
47
+ michael = mock("male")
48
+ michael.stub!(:to_s).and_return("Michael")
49
+ michael.stub!(:gender).and_return("male")
50
+
51
+ lcase.apply(michael, "Michael", {}).should eq("Michael's")
52
+ end
53
+ end
54
+ end
5
55
  end
@@ -17,6 +17,13 @@ describe Tr8n::TranslationKey do
17
17
  Tr8n::Config.init(@english.locale, @translator)
18
18
  end
19
19
 
20
+ after :all do
21
+ [@user, @translator, @user2, @translator2,
22
+ @english, @russian, @spanish].each do |obj|
23
+ obj.destroy
24
+ end
25
+ end
26
+
20
27
  context "creating new translation key" do
21
28
  it "should create a unique hash" do
22
29
  key = Tr8n::TranslationKey.find_or_create("Hello World", "We must start with this sentence!")
@@ -62,6 +69,29 @@ describe Tr8n::TranslationKey do
62
69
  key.translate(@english, {:user => @user2}).should == "Anna updated her profile"
63
70
  end
64
71
  end
72
+ end
73
+
74
+ context "translations" do
75
+ before :all do
76
+ @user = User.create(:first_name => "Mike", :gender => "male")
77
+ @translator = Tr8n::Translator.create!(:name => "Mike", :user => @user, :gender => "male")
78
+
79
+ @user2 = User.create(:first_name => "Anna", :gender => "female")
80
+ @translator2 = Tr8n::Translator.create!(:name => "Anna", :user => @user2, :gender => "female")
81
+
82
+ @english = Tr8n::Language.create!(:locale => "en-US", :english_name => "English")
83
+ @russian = Tr8n::Language.create!(:locale => "ru", :english_name => "Russian")
84
+ @spanish = Tr8n::Language.create!(:locale => "es", :english_name => "Spanish")
85
+
86
+ Tr8n::Config.init(@english.locale, @translator)
87
+ end
88
+
89
+ after :all do
90
+ [@user, @translator, @user2, @translator2,
91
+ @english, @russian, @spanish].each do |obj|
92
+ obj.destroy
93
+ end
94
+ end
65
95
 
66
96
  describe "translating labels into a foreign language" do
67
97
  context "labels with no rules" do
@@ -112,6 +142,232 @@ describe Tr8n::TranslationKey do
112
142
  key.translate(@russian, {:count => 103}).should eq("U vas est 103 soobsheniya.")
113
143
  end
114
144
  end
145
+
146
+
147
+ context "labels with gender rules" do
148
+ it "should return correct translations" do
149
+
150
+ definition = {operator: "is", value: "male"}
151
+ rule1 = Tr8n::GenderRule.create(:language => @russian, :definition => definition)
152
+
153
+ definition = {operator: "is", value: "female"}
154
+ rule2 = Tr8n::GenderRule.create(:language => @russian, :definition => definition)
155
+
156
+ definition = {operator: "is", value: "unknown"}
157
+ rule3 = Tr8n::GenderRule.create(:language => @russian, :definition => definition)
158
+
159
+ key = Tr8n::TranslationKey.find_or_create("{user| Born on:}")
160
+ key.add_translation("Rodilsya:", [{:token=>"user", :rule_id=>[rule1.id]}], @russian, @translator)
161
+ key.add_translation("Rodilas':", [{:token=>"user", :rule_id=>[rule2.id]}], @russian, @translator)
162
+ key.add_translation("Rodilsya/Rodilas':", [{:token=>"user", :rule_id=>[rule3.id]}], @russian, @translator)
163
+
164
+ male = mock("male")
165
+ male.stub!(:to_s).and_return("Michael")
166
+ male.stub!(:gender).and_return("male")
167
+ female = mock("female")
168
+ female.stub!(:to_s).and_return("Anna")
169
+ female.stub!(:gender).and_return("female")
170
+ unknown = mock("unknown")
171
+ unknown.stub!(:to_s).and_return("Alex")
172
+ unknown.stub!(:gender).and_return("unknown")
173
+
174
+ key.translate(@english, {:user => male}).should eq("Born on:")
175
+ key.translate(@english, {:user => female}).should eq("Born on:")
176
+
177
+ key.translate(@russian, {:user => male}).should eq("Rodilsya:")
178
+ key.translate(@russian, {:user => female}).should eq("Rodilas':")
179
+ key.translate(@russian, {:user => unknown}).should eq("Rodilsya/Rodilas':")
180
+
181
+ key = Tr8n::TranslationKey.find_or_create("{user} updated {user|his, her} profile.")
182
+ key.add_translation("{user} obnovil svoi profil'.", [{:token=>"user", :rule_id=>[rule1.id]}], @russian, @translator)
183
+ key.add_translation("{user} obnovila svoi profil'.", [{:token=>"user", :rule_id=>[rule2.id]}], @russian, @translator)
184
+ key.add_translation("{user} obnovil/obnovila svoi profil'.", [{:token=>"user", :rule_id=>[rule3.id]}], @russian, @translator)
185
+
186
+ key.translate(@english, {:user => male}).should eq("Michael updated his profile.")
187
+ key.translate(@english, {:user => female}).should eq("Anna updated her profile.")
188
+
189
+ key.translate(@russian, {:user => male}).should eq("Michael obnovil svoi profil'.")
190
+ key.translate(@russian, {:user => female}).should eq("Anna obnovila svoi profil'.")
191
+ key.translate(@russian, {:user => unknown}).should eq("Alex obnovil/obnovila svoi profil'.")
192
+ end
193
+ end
194
+
195
+ context "labels with mixed rules and tokens" do
196
+ it "should return correct translations" do
197
+ definition = {operator: "is", value: "male"}
198
+ grule1 = Tr8n::GenderRule.create(:language => @russian, :definition => definition)
199
+ definition = {operator: "is", value: "female"}
200
+ grule2 = Tr8n::GenderRule.create(:language => @russian, :definition => definition)
201
+ definition = {operator: "is", value: "unknown"}
202
+ grule3 = Tr8n::GenderRule.create(:language => @russian, :definition => definition)
203
+
204
+ definition = {multipart: true, part1: "ends_in", value1: "1", operator: "and", part2: "does_not_end_in", value2: "11"}
205
+ nrule1 = Tr8n::NumericRule.create(:language => @russian, :definition => definition)
206
+ definition = {multipart: true, part1: "ends_in", value1: "2,3,4", operator: "and", part2: "does_not_end_in", value2: "12,13,14"}
207
+ nrule2 = Tr8n::NumericRule.create(:language => @russian, :definition => definition)
208
+ definition = {multipart: false, part1: "ends_in", value1: "0,5,6,7,8,9,11,12,13,14"}
209
+ nrule3 = Tr8n::NumericRule.create(:language => @russian, :definition => definition)
210
+
211
+ male = mock("male")
212
+ male.stub!(:to_s).and_return("Michael")
213
+ male.stub!(:gender).and_return("male")
214
+ female = mock("female")
215
+ female.stub!(:to_s).and_return("Anna")
216
+ female.stub!(:gender).and_return("female")
217
+ unknown = mock("unknown")
218
+ unknown.stub!(:to_s).and_return("Alex")
219
+ unknown.stub!(:gender).and_return("unknown")
220
+
221
+ key = Tr8n::TranslationKey.find_or_create("Dear {user}, you have [bold: {count||message}].")
222
+ key.add_translation("Dorogoi {user}, u vas est' [bold: {count} soobshenie].", [
223
+ {:token=>"user", :rule_id=>[grule1.id]}, {:token=>"count", :rule_id=>[nrule1.id]}
224
+ ], @russian, @translator)
225
+ key.add_translation("Dorogoi {user}, u vas est' [bold: {count} soobsheniya].", [
226
+ {:token=>"user", :rule_id=>[grule1.id]}, {:token=>"count", :rule_id=>[nrule2.id]}
227
+ ], @russian, @translator)
228
+ key.add_translation("Dorogoi {user}, u vas est' [bold: {count} soobshenii].", [
229
+ {:token=>"user", :rule_id=>[grule1.id]}, {:token=>"count", :rule_id=>[nrule3.id]}
230
+ ], @russian, @translator)
231
+ key.add_translation("Dorogaya {user}, u vas est' [bold: {count} soobshenie].", [
232
+ {:token=>"user", :rule_id=>[grule2.id]}, {:token=>"count", :rule_id=>[nrule1.id]}
233
+ ], @russian, @translator)
234
+ key.add_translation("Dorogaya {user}, u vas est' [bold: {count} soobsheniya].", [
235
+ {:token=>"user", :rule_id=>[grule2.id]}, {:token=>"count", :rule_id=>[nrule2.id]}
236
+ ], @russian, @translator)
237
+ key.add_translation("Dorogaya {user}, u vas est' [bold: {count} soobshenii].", [
238
+ {:token=>"user", :rule_id=>[grule2.id]}, {:token=>"count", :rule_id=>[nrule3.id]}
239
+ ], @russian, @translator)
240
+
241
+ key.translate(@english, {:user => male, :count => 1, :bold => "<b>{$0}</b>"}).should eq("Dear Michael, you have <b>1 message</b>.")
242
+ key.translate(@english, {:user => female, :count => 1, :bold => "<b>{$0}</b>"}).should eq("Dear Anna, you have <b>1 message</b>.")
243
+
244
+ key.translate(@english, {:user => male, :count => 5, :bold => "<b>{$0}</b>"}).should eq("Dear Michael, you have <b>5 messages</b>.")
245
+ key.translate(@english, {:user => female, :count => 5, :bold => "<b>{$0}</b>"}).should eq("Dear Anna, you have <b>5 messages</b>.")
246
+
247
+ key.translate(@russian, {:user => male, :count => 1, :bold => "<b>{$0}</b>"}).should eq("Dorogoi Michael, u vas est' <b>1 soobshenie</b>.")
248
+ key.translate(@russian, {:user => female, :count => 1, :bold => "<b>{$0}</b>"}).should eq("Dorogaya Anna, u vas est' <b>1 soobshenie</b>.")
249
+
250
+ key.translate(@russian, {:user => male, :count => 2, :bold => "<b>{$0}</b>"}).should eq("Dorogoi Michael, u vas est' <b>2 soobsheniya</b>.")
251
+ key.translate(@russian, {:user => female, :count => 2, :bold => "<b>{$0}</b>"}).should eq("Dorogaya Anna, u vas est' <b>2 soobsheniya</b>.")
252
+
253
+ key.translate(@russian, {:user => male, :count => 5, :bold => "<b>{$0}</b>"}).should eq("Dorogoi Michael, u vas est' <b>5 soobshenii</b>.")
254
+ key.translate(@russian, {:user => female, :count => 5, :bold => "<b>{$0}</b>"}).should eq("Dorogaya Anna, u vas est' <b>5 soobshenii</b>.")
255
+ end
256
+ end
257
+
258
+ context "labels with languages cases" do
259
+ describe "when using a possesive case in English" do
260
+ it "should add s or ' at the end of the phrase" do
261
+ michael = mock("male")
262
+ michael.stub!(:to_s).and_return("Michael")
263
+ michael.stub!(:gender).and_return("male")
264
+ anna = mock("female")
265
+ anna.stub!(:to_s).and_return("Anna")
266
+ anna.stub!(:gender).and_return("female")
267
+
268
+ language_case = Tr8n::LanguageCase.create(:language => @english,
269
+ :translator => @translator, :keyword => "pos",
270
+ :latin_name => "Possessive", :application => "phrase")
271
+
272
+ language_case.add_rule({
273
+ part1: "ends_in", value1: "s",
274
+ operation: "append",
275
+ operation_value: "'"
276
+ }, :translator => @translator)
277
+ language_case.add_rule({
278
+ part1: "does_not_end_in",
279
+ value1: "s",
280
+ operation: "append",
281
+ operation_value: "'s"
282
+ }, :translator => @translator)
283
+
284
+ key = Tr8n::TranslationKey.find_or_create("{actor} updated {target::pos} profile.")
285
+ key.translate(@english, {:actor => michael, :target => anna}).should eq("Michael updated Anna's profile.")
286
+ end
287
+ end
288
+
289
+ describe "when using a full ordinal case in English" do
290
+ it "should use first, second, or add th to the end of numbers" do
291
+ lcase = Tr8n::LanguageCase.create(
292
+ :language => @english,
293
+ :translator => @translator,
294
+ :keyword => "ord",
295
+ :description => "The adjective form of the cardinal numbers",
296
+ :latin_name => "Ordinal",
297
+ :application => "phrase"
298
+ )
299
+ lcase.add_rule({
300
+ part1: "is",
301
+ value1: "1",
302
+ operation: "replace",
303
+ operation_value: "first"
304
+ }, :translator => @translator)
305
+ lcase.add_rule({
306
+ part1: "is",
307
+ value1: "2",
308
+ operation: "replace",
309
+ operation_value: "second"
310
+ }, :translator => @translator)
311
+ lcase.add_rule({
312
+ part1: "is",
313
+ value1: "3",
314
+ operation: "replace",
315
+ operation_value: "third"
316
+ }, :translator => @translator)
317
+ lcase.add_rule({
318
+ multipart: "true",
319
+ part1: "ends_in",
320
+ value1: "1",
321
+ operator: "and",
322
+ part2: "does_not_end_in",
323
+ value2: "11",
324
+ operation: "append",
325
+ operation_value: "st"
326
+ }, :translator => @translator)
327
+ lcase.add_rule({
328
+ multipart: "true",
329
+ part1: "ends_in",
330
+ value1: "2",
331
+ operator: "and",
332
+ part2: "does_not_end_in",
333
+ value2: "12",
334
+ operation: "append",
335
+ operation_value: "nd"
336
+ }, :translator => @translator)
337
+ lcase.add_rule({
338
+ multipart: "true",
339
+ part1: "ends_in",
340
+ value1: "3",
341
+ operator: "and",
342
+ part2: "does_not_end_in",
343
+ value2: "13",
344
+ operation: "append",
345
+ operation_value: "rd"
346
+ }, :translator => @translator)
347
+ lcase.add_rule({
348
+ part1: "ends_in",
349
+ value1: "0,4,5,6,7,8,9,11,12,13",
350
+ operation: "append",
351
+ operation_value: "th"
352
+ }, :translator => @translator)
353
+
354
+ @english = Tr8n::Language.find(@english.id)
355
+
356
+ key = Tr8n::TranslationKey.find_or_create("This is your {count::ord} notice!")
357
+ key.translate(@english, {:count => 1}).should eq("This is your first notice!")
358
+ key.translate(@english, {:count => 2}).should eq("This is your second notice!")
359
+ key.translate(@english, {:count => 3}).should eq("This is your third notice!")
360
+ key.translate(@english, {:count => 4}).should eq("This is your 4th notice!")
361
+ key.translate(@english, {:count => 5}).should eq("This is your 5th notice!")
362
+ key.translate(@english, {:count => 12}).should eq("This is your 12th notice!")
363
+ key.translate(@english, {:count => 42}).should eq("This is your 42nd notice!")
364
+ key.translate(@english, {:count => 13}).should eq("This is your 13th notice!")
365
+ key.translate(@english, {:count => 23}).should eq("This is your 23rd notice!")
366
+ end
367
+ end
368
+
369
+ end
370
+
115
371
  end
116
372
 
117
373
  end