socialcast-i18n-js 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +2 -0
  4. data/README.md +324 -0
  5. data/README.rdoc +320 -0
  6. data/Rakefile +13 -0
  7. data/app/assets/javascripts/i18n/translations.js.erb +6 -0
  8. data/app/assets/javascripts/i18n.js +661 -0
  9. data/config/i18n-js.yml +22 -0
  10. data/i18n-js.gemspec +28 -0
  11. data/lib/i18n/js/engine.rb +6 -0
  12. data/lib/i18n/js/file_dependency_processor.rb +17 -0
  13. data/lib/i18n/js/railtie.rb +17 -0
  14. data/lib/i18n/js/translator.rb +56 -0
  15. data/lib/i18n/js/version.rb +10 -0
  16. data/lib/i18n-js/engine.rb +63 -0
  17. data/lib/i18n-js/middleware.rb +59 -0
  18. data/lib/i18n-js/railtie.rb +13 -0
  19. data/lib/i18n-js/rake.rb +16 -0
  20. data/lib/i18n-js/version.rb +10 -0
  21. data/lib/i18n-js.rb +22 -0
  22. data/lib/tasks/i18n-js.rake +17 -0
  23. data/spec/file_dependency_processor_spec.rb +32 -0
  24. data/spec/fixtures/custom_path.yml +2 -0
  25. data/spec/fixtures/default.yml +2 -0
  26. data/spec/fixtures/js_file_per_locale.yml +1 -0
  27. data/spec/fixtures/locales.yml +76 -0
  28. data/spec/fixtures/multiple_conditions.yml +3 -0
  29. data/spec/fixtures/no_config.yml +2 -0
  30. data/spec/fixtures/simple_scope.yml +2 -0
  31. data/spec/i18n_js_spec.rb +11 -0
  32. data/spec/i18n_spec.js +820 -0
  33. data/spec/i18n_spec.rb +205 -0
  34. data/spec/js/currency.spec.js +60 -0
  35. data/spec/js/current_locale.spec.js +19 -0
  36. data/spec/js/dates.spec.js +218 -0
  37. data/spec/js/defaults.spec.js +23 -0
  38. data/spec/js/interpolation.spec.js +28 -0
  39. data/spec/js/jasmine/MIT.LICENSE +20 -0
  40. data/spec/js/jasmine/jasmine-html.js +190 -0
  41. data/spec/js/jasmine/jasmine.css +166 -0
  42. data/spec/js/jasmine/jasmine.js +2476 -0
  43. data/spec/js/jasmine/jasmine_favicon.png +0 -0
  44. data/spec/js/localization.spec.js +41 -0
  45. data/spec/js/numbers.spec.js +124 -0
  46. data/spec/js/placeholder.spec.js +24 -0
  47. data/spec/js/pluralization.spec.js +105 -0
  48. data/spec/js/prepare_options.spec.js +41 -0
  49. data/spec/js/specs.html +46 -0
  50. data/spec/js/translate.spec.js +119 -0
  51. data/spec/js/translations.js +115 -0
  52. data/spec/resources/custom_path.yml +4 -0
  53. data/spec/resources/default.yml +4 -0
  54. data/spec/resources/js_file_per_locale.yml +3 -0
  55. data/spec/resources/locales.yml +76 -0
  56. data/spec/resources/multiple_conditions.yml +6 -0
  57. data/spec/resources/multiple_files.yml +6 -0
  58. data/spec/resources/no_config.yml +2 -0
  59. data/spec/resources/no_scope.yml +3 -0
  60. data/spec/resources/simple_scope.yml +4 -0
  61. data/spec/spec_helper.rb +40 -0
  62. data/spec/translator_spec.rb +45 -0
  63. data/vendor/assets/javascripts/i18n/translations.js.erb +9 -0
  64. data/vendor/assets/javascripts/i18n.js +531 -0
  65. data/vendor/assets/javascripts/underscore.js +1059 -0
  66. metadata +240 -0
data/spec/i18n_spec.rb ADDED
@@ -0,0 +1,205 @@
1
+ require "spec_helper"
2
+
3
+ if File.basename(Rails.root) != "tmp"
4
+ abort <<-TXT
5
+ \e[31;5m
6
+ WARNING: That will remove your project!
7
+ Please go to #{File.expand_path(File.dirname(__FILE__) + "/..")} and run `rake spec`\e[0m
8
+ TXT
9
+ end
10
+
11
+ describe SimplesIdeias::I18n do
12
+ before do
13
+ # Remove temporary directory if already present
14
+ FileUtils.rm_r(Rails.root) if File.exist?(Rails.root)
15
+
16
+ # Create temporary directory to test the files generation
17
+ %w( config public/javascripts ).each do |path|
18
+ FileUtils.mkdir_p Rails.root.join(path)
19
+ end
20
+
21
+ # Overwrite defaut locales path to use fixtures
22
+ I18n.load_path = [File.dirname(__FILE__) + "/resources/locales.yml"]
23
+ end
24
+
25
+ after do
26
+ # Remove temporary directory
27
+ FileUtils.rm_r(Rails.root)
28
+ end
29
+
30
+ it "copies the configuration file" do
31
+ File.should_not be_file(SimplesIdeias::I18n.config_file)
32
+ SimplesIdeias::I18n.setup!
33
+ File.should be_file(SimplesIdeias::I18n.config_file)
34
+ end
35
+
36
+ it "keeps existing configuration file" do
37
+ File.open(SimplesIdeias::I18n.config_file, "w+") {|f| f << "ORIGINAL"}
38
+ SimplesIdeias::I18n.setup!
39
+
40
+ File.read(SimplesIdeias::I18n.config_file).should == "ORIGINAL"
41
+ end
42
+
43
+ it "copies JavaScript library" do
44
+ path = Rails.root.join("public/javascripts/i18n.js")
45
+
46
+ File.should_not be_file(path)
47
+ SimplesIdeias::I18n.setup!
48
+ File.should be_file(path)
49
+ end
50
+
51
+ it "loads configuration file" do
52
+ set_config "default.yml"
53
+ SimplesIdeias::I18n.setup!
54
+
55
+ SimplesIdeias::I18n.config?.should be_true
56
+ SimplesIdeias::I18n.config.should be_kind_of(HashWithIndifferentAccess)
57
+ SimplesIdeias::I18n.config.should_not be_empty
58
+ end
59
+
60
+ it "sets empty hash as configuration when no file is found" do
61
+ SimplesIdeias::I18n.config?.should be_false
62
+ SimplesIdeias::I18n.config.should == {}
63
+ end
64
+
65
+ it "exports messages to default path when configuration file doesn't exist" do
66
+ SimplesIdeias::I18n.export!
67
+ Rails.root.join(SimplesIdeias::I18n.export_dir, "translations.js").should be_file
68
+ end
69
+
70
+ it "exports messages using custom output path" do
71
+ set_config "custom_path.yml"
72
+ SimplesIdeias::I18n.should_receive(:save).with(translations, "public/javascripts/translations/all.js")
73
+ SimplesIdeias::I18n.export!
74
+ end
75
+
76
+ it "sets default scope to * when not specified" do
77
+ set_config "no_scope.yml"
78
+ SimplesIdeias::I18n.should_receive(:save).with(translations, "public/javascripts/no_scope.js")
79
+ SimplesIdeias::I18n.export!
80
+ end
81
+
82
+ it "exports to multiple files" do
83
+ set_config "multiple_files.yml"
84
+ SimplesIdeias::I18n.export!
85
+
86
+ File.should be_file(Rails.root.join("public/javascripts/all.js"))
87
+ File.should be_file(Rails.root.join("public/javascripts/tudo.js"))
88
+ end
89
+
90
+ it "ignores an empty config file" do
91
+ set_config "no_config.yml"
92
+ SimplesIdeias::I18n.export!
93
+ Rails.root.join(SimplesIdeias::I18n.export_dir, "translations.js").should be_file
94
+ end
95
+
96
+ it "exports to a JS file per available locale" do
97
+ set_config "js_file_per_locale.yml"
98
+ SimplesIdeias::I18n.export!
99
+
100
+ File.should be_file(Rails.root.join("public/javascripts/i18n/en.js"))
101
+ end
102
+
103
+ it "exports with multiple conditions" do
104
+ set_config "multiple_conditions.yml"
105
+ SimplesIdeias::I18n.export!
106
+ File.should be_file(Rails.root.join("public/javascripts/bitsnpieces.js"))
107
+ end
108
+
109
+ it "filters translations using scope *.date.formats" do
110
+ result = SimplesIdeias::I18n.filter(translations, "*.date.formats")
111
+ result[:en][:date].keys.should == [:formats]
112
+ result[:fr][:date].keys.should == [:formats]
113
+ end
114
+
115
+ it "filters translations using scope [*.date.formats, *.number.currency.format]" do
116
+ result = SimplesIdeias::I18n.scoped_translations(["*.date.formats", "*.number.currency.format"])
117
+ result[:en].keys.collect(&:to_s).sort.should == %w[ date number ]
118
+ result[:fr].keys.collect(&:to_s).sort.should == %w[ date number ]
119
+ end
120
+
121
+ it "filters translations using multi-star scope" do
122
+ result = SimplesIdeias::I18n.scoped_translations("*.*.formats")
123
+
124
+ result[:en].keys.collect(&:to_s).sort.should == %w[ date time ]
125
+ result[:fr].keys.collect(&:to_s).sort.should == %w[ date time ]
126
+
127
+ result[:en][:date].keys.should == [:formats]
128
+ result[:en][:time].keys.should == [:formats]
129
+
130
+ result[:fr][:date].keys.should == [:formats]
131
+ result[:fr][:time].keys.should == [:formats]
132
+ end
133
+
134
+ it "filters translations using alternated stars" do
135
+ result = SimplesIdeias::I18n.scoped_translations("*.admin.*.title")
136
+
137
+ result[:en][:admin].keys.collect(&:to_s).sort.should == %w[ edit show ]
138
+ result[:fr][:admin].keys.collect(&:to_s).sort.should == %w[ edit show ]
139
+
140
+ result[:en][:admin][:show][:title].should == "Show"
141
+ result[:fr][:admin][:show][:title].should == "Visualiser"
142
+
143
+ result[:en][:admin][:edit][:title].should == "Edit"
144
+ result[:fr][:admin][:edit][:title].should == "Editer"
145
+ end
146
+
147
+ it "performs a deep merge" do
148
+ target = {:a => {:b => 1}}
149
+ result = SimplesIdeias::I18n.deep_merge(target, {:a => {:c => 2}})
150
+
151
+ result[:a].should == {:b => 1, :c => 2}
152
+ end
153
+
154
+ it "performs a banged deep merge" do
155
+ target = {:a => {:b => 1}}
156
+ SimplesIdeias::I18n.deep_merge!(target, {:a => {:c => 2}})
157
+
158
+ target[:a].should == {:b => 1, :c => 2}
159
+ end
160
+
161
+ it "updates the javascript library" do
162
+ FakeWeb.register_uri(:get, "https://raw.github.com/fnando/i18n-js/master/vendor/assets/javascripts/i18n.js", :body => "UPDATED")
163
+
164
+ SimplesIdeias::I18n.setup!
165
+ SimplesIdeias::I18n.update!
166
+ File.read(SimplesIdeias::I18n.javascript_file).should == "UPDATED"
167
+ end
168
+
169
+ describe "#export_dir" do
170
+ it "detects asset pipeline support" do
171
+ SimplesIdeias::I18n.stub :has_asset_pipeline? => true
172
+ SimplesIdeias::I18n.export_dir == "vendor/assets/javascripts"
173
+ end
174
+
175
+ it "detects older Rails" do
176
+ SimplesIdeias::I18n.stub :has_asset_pipeline? => false
177
+ SimplesIdeias::I18n.export_dir.to_s.should == "public/javascripts"
178
+ end
179
+ end
180
+
181
+ describe "#has_asset_pipeline?" do
182
+ it "detects support" do
183
+ Rails.stub_chain(:configuration, :assets, :enabled => true)
184
+ SimplesIdeias::I18n.should have_asset_pipeline
185
+ end
186
+
187
+ it "skips support" do
188
+ SimplesIdeias::I18n.should_not have_asset_pipeline
189
+ end
190
+ end
191
+
192
+ private
193
+ # Set the configuration as the current one
194
+ def set_config(path)
195
+ config = HashWithIndifferentAccess.new(YAML.load_file(File.dirname(__FILE__) + "/resources/#{path}"))
196
+ SimplesIdeias::I18n.stub(:config? => true)
197
+ SimplesIdeias::I18n.stub(:config => config)
198
+ end
199
+
200
+ # Shortcut to SimplesIdeias::I18n.translations
201
+ def translations
202
+ SimplesIdeias::I18n.translations
203
+ end
204
+ end
205
+
@@ -0,0 +1,60 @@
1
+ var I18n = require("../../app/assets/javascripts/i18n")
2
+ , Translations = require("./translations")
3
+ ;
4
+
5
+ describe("Currency", function(){
6
+ var actual, expected;
7
+
8
+ beforeEach(function() {
9
+ I18n.reset();
10
+ I18n.translations = Translations();
11
+ });
12
+
13
+ it("formats currency with default settings", function(){
14
+ expect(I18n.toCurrency(100.99)).toEqual("$100.99");
15
+ expect(I18n.toCurrency(1000.99)).toEqual("$1,000.99");
16
+ });
17
+
18
+ it("formats currency with custom settings", function(){
19
+ I18n.translations.en.number = {
20
+ currency: {
21
+ format: {
22
+ format: "%n %u",
23
+ unit: "USD",
24
+ delimiter: ".",
25
+ separator: ",",
26
+ precision: 2
27
+ }
28
+ }
29
+ };
30
+
31
+ expect(I18n.toCurrency(12)).toEqual("12,00 USD");
32
+ expect(I18n.toCurrency(123)).toEqual("123,00 USD");
33
+ expect(I18n.toCurrency(1234.56)).toEqual("1.234,56 USD");
34
+ });
35
+
36
+ it("formats currency with custom settings and partial overriding", function(){
37
+ I18n.translations.en.number = {
38
+ currency: {
39
+ format: {
40
+ format: "%n %u",
41
+ unit: "USD",
42
+ delimiter: ".",
43
+ separator: ",",
44
+ precision: 2
45
+ }
46
+ }
47
+ };
48
+
49
+ expect(I18n.toCurrency(12, {precision: 0})).toEqual("12 USD");
50
+ expect(I18n.toCurrency(123, {unit: "bucks"})).toEqual("123,00 bucks");
51
+ });
52
+
53
+ it("formats currency with some custom options that should be merged with default options", function(){
54
+ expect(I18n.toCurrency(1234, {precision: 0})).toEqual("$1,234");
55
+ expect(I18n.toCurrency(1234, {unit: "º"})).toEqual("º1,234.00");
56
+ expect(I18n.toCurrency(1234, {separator: "-"})).toEqual("$1,234-00");
57
+ expect(I18n.toCurrency(1234, {delimiter: "-"})).toEqual("$1-234.00");
58
+ expect(I18n.toCurrency(1234, {format: "%u %n"})).toEqual("$ 1,234.00");
59
+ });
60
+ });
@@ -0,0 +1,19 @@
1
+ var I18n = require("../../app/assets/javascripts/i18n");
2
+
3
+ describe("Current locale", function(){
4
+ beforeEach(function(){
5
+ I18n.reset();
6
+ });
7
+
8
+ it("returns I18n.locale", function(){
9
+ I18n.locale = "pt-BR";
10
+ expect(I18n.currentLocale()).toEqual("pt-BR");
11
+ });
12
+
13
+ it("returns I18n.defaultLocale", function(){
14
+ I18n.locale = null;
15
+ I18n.defaultLocale = "pt-BR";
16
+
17
+ expect(I18n.currentLocale()).toEqual("pt-BR");
18
+ });
19
+ });
@@ -0,0 +1,218 @@
1
+ var I18n = require("../../app/assets/javascripts/i18n")
2
+ , Translations = require("./translations")
3
+ ;
4
+
5
+ describe("Dates", function(){
6
+ var actual, expected;
7
+
8
+ beforeEach(function() {
9
+ I18n.reset();
10
+ I18n.translations = Translations();
11
+ });
12
+
13
+ it("parses date", function(){
14
+ expected = new Date(2009, 0, 24, 0, 0, 0);
15
+ actual = I18n.parseDate("2009-01-24");
16
+ expect(actual.toString()).toEqual(expected.toString());
17
+
18
+ expected = new Date(2009, 0, 24, 0, 15, 0);
19
+ actual = I18n.parseDate("2009-01-24 00:15:00");
20
+ expect(actual.toString()).toEqual(expected.toString());
21
+
22
+ expected = new Date(2009, 0, 24, 0, 0, 15);
23
+ actual = I18n.parseDate("2009-01-24 00:00:15");
24
+ expect(actual.toString()).toEqual(expected.toString());
25
+
26
+ expected = new Date(2009, 0, 24, 15, 33, 44);
27
+ actual = I18n.parseDate("2009-01-24 15:33:44");
28
+ expect(actual.toString()).toEqual(expected.toString());
29
+
30
+ expected = new Date(2009, 0, 24, 0, 0, 0);
31
+ actual = I18n.parseDate(expected.getTime());
32
+ expect(actual.toString()).toEqual(expected.toString());
33
+
34
+ expected = new Date(2009, 0, 24, 0, 0, 0);
35
+ actual = I18n.parseDate("01/24/2009");
36
+ expect(actual.toString()).toEqual(expected.toString());
37
+
38
+ expected = new Date(2009, 0, 24, 14, 33, 55);
39
+ actual = I18n.parseDate(expected).toString();
40
+ expect(actual).toEqual(expected.toString());
41
+
42
+ expected = new Date(2009, 0, 24, 15, 33, 44);
43
+ actual = I18n.parseDate("2009-01-24T15:33:44");
44
+ expect(actual.toString()).toEqual(expected.toString());
45
+
46
+ expected = new Date(Date.UTC(2011, 6, 20, 12, 51, 55));
47
+ actual = I18n.parseDate("2011-07-20T12:51:55+0000");
48
+ expect(actual.toString()).toEqual(expected.toString());
49
+
50
+ expected = new Date(Date.UTC(2011, 6, 20, 13, 03, 39));
51
+ actual = I18n.parseDate("Wed Jul 20 13:03:39 +0000 2011");
52
+ expect(actual.toString()).toEqual(expected.toString());
53
+
54
+ expected = new Date(Date.UTC(2009, 0, 24, 15, 33, 44));
55
+ actual = I18n.parseDate("2009-01-24T15:33:44Z");
56
+ expect(actual.toString()).toEqual(expected.toString());
57
+ });
58
+
59
+ it("formats date", function(){
60
+ I18n.locale = "pt-BR";
61
+
62
+ // 2009-04-26 19:35:44 (Sunday)
63
+ var date = new Date(2009, 3, 26, 19, 35, 44);
64
+
65
+ // short week day
66
+ expect(I18n.strftime(date, "%a")).toEqual("Dom");
67
+
68
+ // full week day
69
+ expect(I18n.strftime(date, "%A")).toEqual("Domingo");
70
+
71
+ // short month
72
+ expect(I18n.strftime(date, "%b")).toEqual("Abr");
73
+
74
+ // full month
75
+ expect(I18n.strftime(date, "%B")).toEqual("Abril");
76
+
77
+ // day
78
+ expect(I18n.strftime(date, "%d")).toEqual("26");
79
+
80
+ // 24-hour
81
+ expect(I18n.strftime(date, "%H")).toEqual("19");
82
+
83
+ // 12-hour
84
+ expect(I18n.strftime(date, "%I")).toEqual("07");
85
+
86
+ // month
87
+ expect(I18n.strftime(date, "%m")).toEqual("04");
88
+
89
+ // minutes
90
+ expect(I18n.strftime(date, "%M")).toEqual("35");
91
+
92
+ // meridian
93
+ expect(I18n.strftime(date, "%p")).toEqual("PM");
94
+
95
+ // seconds
96
+ expect(I18n.strftime(date, "%S")).toEqual("44");
97
+
98
+ // week day
99
+ expect(I18n.strftime(date, "%w")).toEqual("0");
100
+
101
+ // short year
102
+ expect(I18n.strftime(date, "%y")).toEqual("09");
103
+
104
+ // full year
105
+ expect(I18n.strftime(date, "%Y")).toEqual("2009");
106
+ });
107
+
108
+ it("formats date without padding", function(){
109
+ I18n.locale = "pt-BR";
110
+
111
+ // 2009-04-26 19:35:44 (Sunday)
112
+ var date = new Date(2009, 3, 9, 7, 8, 9);
113
+
114
+ // 24-hour without padding
115
+ expect(I18n.strftime(date, "%-H")).toEqual("7");
116
+
117
+ // 12-hour without padding
118
+ expect(I18n.strftime(date, "%-I")).toEqual("7");
119
+
120
+ // minutes without padding
121
+ expect(I18n.strftime(date, "%-M")).toEqual("8");
122
+
123
+ // seconds without padding
124
+ expect(I18n.strftime(date, "%-S")).toEqual("9");
125
+
126
+ // short year without padding
127
+ expect(I18n.strftime(date, "%-y")).toEqual("9");
128
+
129
+ // month without padding
130
+ expect(I18n.strftime(date, "%-m")).toEqual("4");
131
+
132
+ // day without padding
133
+ expect(I18n.strftime(date, "%-d")).toEqual("9");
134
+ expect(I18n.strftime(date, "%e")).toEqual("9");
135
+ });
136
+
137
+ it("formats date with padding", function(){
138
+ I18n.locale = "pt-BR";
139
+
140
+ // 2009-04-26 19:35:44 (Sunday)
141
+ var date = new Date(2009, 3, 9, 7, 8, 9);
142
+
143
+ // 24-hour
144
+ expect(I18n.strftime(date, "%H")).toEqual("07");
145
+
146
+ // 12-hour
147
+ expect(I18n.strftime(date, "%I")).toEqual("07");
148
+
149
+ // minutes
150
+ expect(I18n.strftime(date, "%M")).toEqual("08");
151
+
152
+ // seconds
153
+ expect(I18n.strftime(date, "%S")).toEqual("09");
154
+
155
+ // short year
156
+ expect(I18n.strftime(date, "%y")).toEqual("09");
157
+
158
+ // month
159
+ expect(I18n.strftime(date, "%m")).toEqual("04");
160
+
161
+ // day
162
+ expect(I18n.strftime(date, "%d")).toEqual("09");
163
+ });
164
+
165
+ it("formats date with negative time zone", function(){
166
+ I18n.locale = "pt-BR";
167
+ var date = new Date(2009, 3, 26, 19, 35, 44);
168
+
169
+ spyOn(date, "getTimezoneOffset").andReturn(345);
170
+
171
+ expect(I18n.strftime(date, "%z")).toMatch(/^(\+|-)[\d]{4}$/);
172
+ expect(I18n.strftime(date, "%z")).toEqual("-0545");
173
+ });
174
+
175
+ it("formats date with positive time zone", function(){
176
+ I18n.locale = "pt-BR";
177
+ var date = new Date(2009, 3, 26, 19, 35, 44);
178
+
179
+ spyOn(date, "getTimezoneOffset").andReturn(-345);
180
+
181
+ expect(I18n.strftime(date, "%z")).toMatch(/^(\+|-)[\d]{4}$/);
182
+ expect(I18n.strftime(date, "%z")).toEqual("+0545");
183
+ });
184
+
185
+ it("formats date with custom meridian", function(){
186
+ I18n.locale = "en-US";
187
+ var date = new Date(2009, 3, 26, 19, 35, 44);
188
+ expect(I18n.strftime(date, "%p")).toEqual("pm");
189
+ });
190
+
191
+ it("formats date with meridian boundaries", function(){
192
+ I18n.locale = "en-US";
193
+ var date = new Date(2009, 3, 26, 0, 35, 44);
194
+ expect(I18n.strftime(date, "%p")).toEqual("am");
195
+
196
+ date = new Date(2009, 3, 26, 12, 35, 44);
197
+ expect(I18n.strftime(date, "%p")).toEqual("pm");
198
+ });
199
+
200
+ it("formats date using 12-hours format", function(){
201
+ I18n.locale = "pt-BR";
202
+ var date = new Date(2009, 3, 26, 19, 35, 44);
203
+ expect(I18n.strftime(date, "%I")).toEqual("07");
204
+
205
+ date = new Date(2009, 3, 26, 12, 35, 44);
206
+ expect(I18n.strftime(date, "%I")).toEqual("12");
207
+
208
+ date = new Date(2009, 3, 26, 0, 35, 44);
209
+ expect(I18n.strftime(date, "%I")).toEqual("12");
210
+ });
211
+
212
+ it("defaults to English", function() {
213
+ I18n.locale = "wk";
214
+
215
+ var date = new Date(2009, 3, 26, 19, 35, 44);
216
+ expect(I18n.strftime(date, "%a")).toEqual("Sun");
217
+ });
218
+ });
@@ -0,0 +1,23 @@
1
+ var I18n = require("../../app/assets/javascripts/i18n");
2
+
3
+ describe("Defaults", function(){
4
+ beforeEach(function(){
5
+ I18n.reset();
6
+ });
7
+
8
+ it("sets the default locale", function(){
9
+ expect(I18n.defaultLocale).toEqual("en");
10
+ });
11
+
12
+ it("sets current locale", function(){
13
+ expect(I18n.locale).toEqual("en");
14
+ });
15
+
16
+ it("sets default separator", function(){
17
+ expect(I18n.defaultSeparator).toEqual(".");
18
+ });
19
+
20
+ it("sets fallback", function(){
21
+ expect(I18n.fallbacks).toEqual(false);
22
+ });
23
+ });
@@ -0,0 +1,28 @@
1
+ var I18n = require("../../app/assets/javascripts/i18n")
2
+ , Translations = require("./translations")
3
+ ;
4
+
5
+ describe("Interpolation", function(){
6
+ var actual, expected;
7
+
8
+ beforeEach(function(){
9
+ I18n.reset();
10
+ I18n.translations = Translations();
11
+ });
12
+
13
+ it("performs single interpolation", function(){
14
+ actual = I18n.t("greetings.name", {name: "John Doe"});
15
+ expect(actual).toEqual("Hello John Doe!");
16
+ });
17
+
18
+ it("performs multiple interpolations", function(){
19
+ actual = I18n.t("profile.details", {name: "John Doe", age: 27});
20
+ expect(actual).toEqual("John Doe is 27-years old");
21
+ });
22
+
23
+ it("performs interpolation with the count option", function(){
24
+ expect(I18n.t("inbox", {count: 0})).toEqual("You have no messages");
25
+ expect(I18n.t("inbox", {count: 1})).toEqual("You have 1 message");
26
+ expect(I18n.t("inbox", {count: 5})).toEqual("You have 5 messages");
27
+ });
28
+ });
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2011 Pivotal Labs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.