tr8n 3.2.0 → 3.2.1

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