i18n-js 3.0.0.rc6 → 3.0.0.rc7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +11 -2
- data/Appraisals +1 -1
- data/CHANGELOG.md +22 -0
- data/README.md +65 -21
- data/app/assets/javascripts/i18n.js +8 -5
- data/gemfiles/i18n_0_6.gemfile +1 -1
- data/i18n-js.gemspec +3 -0
- data/lib/i18n/js.rb +37 -21
- data/lib/i18n/js/dependencies.rb +4 -0
- data/lib/i18n/js/engine.rb +2 -1
- data/lib/i18n/js/utils.rb +26 -0
- data/lib/i18n/js/version.rb +1 -1
- data/spec/i18n_js_spec.rb +155 -4
- data/spec/js/interpolation.spec.js +5 -0
- data/spec/js/specs.html +1 -0
- data/spec/js/translate.spec.js +9 -0
- data/spec/js/translations.js +2 -0
- data/spec/js/utility_functions.spec.js +20 -0
- data/spec/spec_helper.rb +3 -3
- metadata +26 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4377851d9bebcdaf860e76c466587f7486255752
|
4
|
+
data.tar.gz: 9b52dbf3c12aca86c6de92073323dcb5dbeb02f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d33c4c88cdbcbeda6233f65a7455d5cfec3b958f3b4aa74f04cbe0ecd4896f7fdd9ee7a853deaae44c932ae9d127146128df24a00f6a2956c31c4f73f8474738
|
7
|
+
data.tar.gz: f8333679e32ad823e9c5946734c031f761609dc30ac8a15b143b030d2d85e6c68dbba0073192a020da39a4aaa1057ae1cad4e60f47459c86dd03b3d3d34dcce2
|
data/.travis.yml
CHANGED
@@ -1,10 +1,19 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
3
|
- 1.9.3
|
4
|
-
- 2.0
|
5
|
-
- 2.1
|
4
|
+
- 2.0
|
5
|
+
- 2.1
|
6
|
+
- 2.2
|
7
|
+
- ruby-head
|
6
8
|
script: "bundle exec rake spec"
|
7
9
|
before_install: # Need to install npm to test js
|
8
10
|
- sudo apt-get update
|
9
11
|
- sudo apt-get install npm
|
10
12
|
- npm install jasmine-node@1.14.2
|
13
|
+
gemfile:
|
14
|
+
- gemfiles/i18n_0_6.gemfile
|
15
|
+
matrix:
|
16
|
+
fast_finish: true
|
17
|
+
allow_failures:
|
18
|
+
- rvm: 2.2
|
19
|
+
- rvm: ruby-head
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
|
2
|
+
## Unreleased
|
3
|
+
|
4
|
+
### enhancements
|
5
|
+
|
6
|
+
- The Rails Engine initializer is now named as `i18n-js.register_preprocessor` (https://github.com/fnando/i18n-js/pull/261)
|
7
|
+
- Rename `I18n::JS.config_file` to `I18n::JS.config_file_path` and make it configurable
|
8
|
+
Expected a `String`, default is still `config/i18n-js.yml`
|
9
|
+
- When running `rake i18n:js:export`, the `i18n.js` will also be exported to `I18n::JS.export_i18n_js_dir_path` by default
|
10
|
+
- Add `I18n::JS.export_i18n_js_dir_path`
|
11
|
+
Expected a `String`, default is `public/javascripts`
|
12
|
+
Set to `nil` will disable exporting `i18n.js`
|
13
|
+
|
14
|
+
### bug fixes
|
15
|
+
|
16
|
+
- Prevent toString() call on `undefined` when there is a missing interpolation value
|
17
|
+
- Added support for Rails instances without Sprockets object (https://github.com/fnando/i18n-js/pull/241)
|
18
|
+
- Fix `DEFAULT_OPTIONS` in `i18n.js` which contained an excessive comma
|
19
|
+
- Fix `nil` values are exported into JS files which causes strange translation error
|
20
|
+
- Fix pattern to replace all escaped $ in I18n.translate
|
21
|
+
- Fix JS `I18n.lookup` modifies existing locales accidentally
|
22
|
+
|
1
23
|
## 3.0.0.rc6
|
2
24
|
|
3
25
|
### enhancements
|
data/README.md
CHANGED
@@ -32,37 +32,42 @@ If you're using the [asset pipeline](http://guides.rubyonrails.org/asset_pipelin
|
|
32
32
|
then you must add the following line to your `app/assets/javascripts/application.js`.
|
33
33
|
|
34
34
|
```javascript
|
35
|
+
//
|
36
|
+
// This is optional (in case you have `I18n is not defined` error)
|
37
|
+
// If you want to put this line, you must put it BEFORE `i18n/translations`
|
38
|
+
//= require i18n
|
39
|
+
//
|
40
|
+
// This is a must
|
35
41
|
//= require i18n/translations
|
36
42
|
```
|
37
43
|
|
38
44
|
#### Rails app without [Asset Pipeline](http://guides.rubyonrails.org/asset_pipeline.html)
|
39
45
|
|
40
|
-
If you're not using the asset pipeline, download the JavaScript file at
|
41
|
-
<https://github.com/fnando/i18n-js/tree/master/lib/i18n.js> and load it on your page.
|
42
|
-
Also load the `translations.js` file.
|
43
46
|
|
47
|
+
First, put this in your `application.html` (layout file).
|
48
|
+
Then get the JS files following the instructions below.
|
44
49
|
```erb
|
45
|
-
|
50
|
+
<%# This is just an example, you can put `i18n.js` and `translations.js` anywhere you like %>
|
51
|
+
<%# Unlike the Asset Pipeline example, you need to require both **in order** %>
|
52
|
+
<%= javascript_include_tag "i18n" %>
|
53
|
+
<%= javascript_include_tag "translations" %>
|
46
54
|
```
|
47
55
|
|
48
|
-
|
49
|
-
Just add it to your `config/application.rb` file.
|
50
|
-
Don't add this middleware if you are using [asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)!
|
56
|
+
**There are two ways to get `translations.js`.**
|
51
57
|
|
52
|
-
|
58
|
+
1. This `translations.js` file can be automatically generated by the `I18n::JS::Middleware`.
|
59
|
+
Just add `config.middleware.use I18n::JS::Middleware` to your `config/application.rb` file.
|
60
|
+
Notice: Don't add this middleware if you are using [asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html)!
|
61
|
+
2. If you can't or prefer not to generate this file,
|
62
|
+
you can move the middleware line to your `config/environments/development.rb` file
|
63
|
+
and run `rake i18n:js:export` before deploying.
|
64
|
+
This will export all translation files, including the custom scopes
|
65
|
+
you may have defined on `config/i18n-js.yml`.
|
66
|
+
If `I18n.available_locales` is set (e.g. in your Rails `config/application.rb` file)
|
67
|
+
then only the specified locales will be exported.
|
68
|
+
Current version of `i18n.js` will also be exported to avoid version mismatching by downloading.
|
53
69
|
|
54
|
-
|
55
|
-
it by running the following command. Move the middleware line to your
|
56
|
-
`config/environments/development.rb` file and run the following command before
|
57
|
-
deploying.
|
58
|
-
|
59
|
-
$ rake i18n:js:export
|
60
|
-
|
61
|
-
This will export all translation files, including the custom scopes you may have
|
62
|
-
defined on `config/i18n-js.yml`. If `I18n.available_locales` is set (e.g. in your
|
63
|
-
Rails `config/application.rb` file) then only the specified locales will be exported.
|
64
|
-
|
65
|
-
#### Export Configuration
|
70
|
+
#### Export Configuration (For translations)
|
66
71
|
|
67
72
|
Exported translation files generated by `I18n::JS::Middleware` or `rake i18n:js:export` can be customized with config file `config/i18n-js.yml` (use `rails generate i18n:js:config` to create it). You can even get more files generated to different folders and with different translations to best suit your needs. But this does not affect anything if you use Asset Pipeline.
|
68
73
|
|
@@ -102,6 +107,18 @@ translations:
|
|
102
107
|
<% end %>
|
103
108
|
```
|
104
109
|
|
110
|
+
#### Export Configuration (For other things)
|
111
|
+
- `I18n::JS.config_file_path`
|
112
|
+
Expected Type: `String`
|
113
|
+
Default: `config/i18n-js.yml`
|
114
|
+
Behaviour: Try to read the config file from that location
|
115
|
+
- `I18n::JS.export_i18n_js_dir_path`
|
116
|
+
Expected Type: `String`
|
117
|
+
Default: `public/javascripts`
|
118
|
+
Behaviour:
|
119
|
+
- Any `String`: considered as a relative path for a folder to `Rails.root` and export `i18n.js` to that folder for `rake i18n:js:export`
|
120
|
+
- `nil`: Disable `i18n.js` exporting
|
121
|
+
|
105
122
|
To find more examples on how to use the configuration file please refer to the tests.
|
106
123
|
|
107
124
|
#### Vanilla JavaScript
|
@@ -213,7 +230,8 @@ The sample above expects the following translation:
|
|
213
230
|
If you need special rules just define them for your language, for example Russian, just add a new pluralizer:
|
214
231
|
|
215
232
|
I18n.pluralization["ru"] = function (count) {
|
216
|
-
|
233
|
+
var key = count % 10 == 1 && count % 100 != 11 ? "one" : [2, 3, 4].indexOf(count % 10) >= 0 && [12, 13, 14].indexOf(count % 100) < 0 ? "few" : count % 10 == 0 || [5, 6, 7, 8, 9].indexOf(count % 10) >= 0 || [11, 12, 13, 14].indexOf(count % 100) >= 0 ? "many" : "other";
|
234
|
+
return [key];
|
217
235
|
};
|
218
236
|
|
219
237
|
You can find all rules on <http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html>.
|
@@ -349,6 +367,32 @@ The only requirement is that you need to set the `translations` attribute like f
|
|
349
367
|
message: "Uma mensagem especial para você"
|
350
368
|
}
|
351
369
|
|
370
|
+
## Known Issues
|
371
|
+
|
372
|
+
### Missing translations in precompiled file(s) after adding any new locale file
|
373
|
+
|
374
|
+
Due to the design of `sprockets`:
|
375
|
+
- `depend_on` only takes file paths, not directory paths
|
376
|
+
- registered `preprocessors` are only run when fingerprint of any asset file, including `.erb` files, is changed
|
377
|
+
|
378
|
+
New locale files won't be picked up unless any existing locale file content is changed.
|
379
|
+
You can workaround it manually by running
|
380
|
+
```bash
|
381
|
+
$ rake assets:clobber
|
382
|
+
```
|
383
|
+
to clear the asset cache.
|
384
|
+
**Or**
|
385
|
+
Change something in existing locale file.
|
386
|
+
**Or**
|
387
|
+
Change `config.assets.version`
|
388
|
+
|
389
|
+
**Note:** `rake assets:clobber` will also remove all fingerprinted assets.
|
390
|
+
If you are precompiling assets on target machine(s),
|
391
|
+
old assets might be removed and cannot be served in cached pages.
|
392
|
+
|
393
|
+
Please see issue #213 for detail & related discussion.
|
394
|
+
|
395
|
+
|
352
396
|
## Maintainer
|
353
397
|
|
354
398
|
- Nando Vieira - <http://nandovieira.com.br>
|
@@ -65,7 +65,7 @@
|
|
65
65
|
defaultSeparator: ".",
|
66
66
|
placeholder: /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm,
|
67
67
|
fallbacks: false,
|
68
|
-
translations: {}
|
68
|
+
translations: {}
|
69
69
|
};
|
70
70
|
|
71
71
|
I18n.reset = function() {
|
@@ -228,7 +228,7 @@
|
|
228
228
|
I18n.lookup = function(scope, options) {
|
229
229
|
options = this.prepareOptions(options);
|
230
230
|
|
231
|
-
var locales = this.locales.get(options.locale)
|
231
|
+
var locales = this.locales.get(options.locale).slice()
|
232
232
|
, requestedLocale = locales[0]
|
233
233
|
, locale
|
234
234
|
, scopes
|
@@ -399,12 +399,15 @@
|
|
399
399
|
return message;
|
400
400
|
}
|
401
401
|
|
402
|
+
var value;
|
403
|
+
|
402
404
|
while (matches.length) {
|
403
405
|
placeholder = matches.shift();
|
404
406
|
name = placeholder.replace(this.placeholder, "$1");
|
405
|
-
value = options[name].toString().replace(/\$/gm, "_#$#_");
|
406
407
|
|
407
|
-
if (
|
408
|
+
if (this.isSet(options[name])) {
|
409
|
+
value = options[name].toString().replace(/\$/gm, "_#$#_");
|
410
|
+
} else {
|
408
411
|
value = this.missingPlaceholder(placeholder, message);
|
409
412
|
}
|
410
413
|
|
@@ -412,7 +415,7 @@
|
|
412
415
|
message = message.replace(regex, value);
|
413
416
|
}
|
414
417
|
|
415
|
-
return message.replace(
|
418
|
+
return message.replace(/_#\$#_/g, "$");
|
416
419
|
};
|
417
420
|
|
418
421
|
// Pluralize the given scope using the `count` value.
|
data/gemfiles/i18n_0_6.gemfile
CHANGED
data/i18n-js.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = "http://rubygems.org/gems/i18n-js"
|
12
12
|
s.summary = "It's a small library to provide the Rails I18n translations on the Javascript."
|
13
13
|
s.description = s.summary
|
14
|
+
s.license = "MIT"
|
14
15
|
|
15
16
|
s.files = `git ls-files`.split("\n")
|
16
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -24,4 +25,6 @@ Gem::Specification.new do |s|
|
|
24
25
|
s.add_development_dependency "rake"
|
25
26
|
s.add_development_dependency "pry-meta"
|
26
27
|
s.add_development_dependency "gem-release", ">= 0.7"
|
28
|
+
|
29
|
+
s.required_ruby_version = ">= 1.9.3"
|
27
30
|
end
|
data/lib/i18n/js.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "i18n"
|
2
2
|
require "fileutils"
|
3
3
|
|
4
|
+
require "i18n/js/utils"
|
5
|
+
|
4
6
|
module I18n
|
5
7
|
module JS
|
6
8
|
require "i18n/js/dependencies"
|
@@ -9,20 +11,23 @@ module I18n
|
|
9
11
|
require "i18n/js/engine"
|
10
12
|
end
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
|
15
|
-
end
|
14
|
+
DEFAULT_CONFIG_PATH = "config/i18n-js.yml"
|
15
|
+
DEFAULT_EXPORT_DIR_PATH = "public/javascripts"
|
16
16
|
|
17
17
|
# The configuration file. This defaults to the `config/i18n-js.yml` file.
|
18
18
|
#
|
19
|
-
def self.
|
20
|
-
@
|
19
|
+
def self.config_file_path
|
20
|
+
@config_file_path ||= DEFAULT_CONFIG_PATH
|
21
|
+
end
|
22
|
+
def self.config_file_path=(new_path)
|
23
|
+
@config_file_path = new_path
|
21
24
|
end
|
22
25
|
|
23
26
|
# Export translations to JavaScript, considering settings
|
24
27
|
# from configuration file
|
25
28
|
def self.export
|
29
|
+
export_i18n_js
|
30
|
+
|
26
31
|
translation_segments.each do |filename, translations|
|
27
32
|
save(translations, filename)
|
28
33
|
end
|
@@ -59,14 +64,10 @@ module I18n
|
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
62
|
-
def self.export_dir
|
63
|
-
"public/javascripts"
|
64
|
-
end
|
65
|
-
|
66
67
|
def self.filtered_translations
|
67
68
|
{}.tap do |result|
|
68
69
|
translation_segments.each do |filename, translations|
|
69
|
-
deep_merge!(result, translations)
|
70
|
+
Utils.deep_merge!(result, translations)
|
70
71
|
end
|
71
72
|
end
|
72
73
|
end
|
@@ -75,7 +76,7 @@ module I18n
|
|
75
76
|
if config? && config[:translations]
|
76
77
|
configured_segments
|
77
78
|
else
|
78
|
-
{"#{
|
79
|
+
{"#{DEFAULT_EXPORT_DIR_PATH}/translations.js" => translations}
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -83,7 +84,7 @@ module I18n
|
|
83
84
|
# custom output directory
|
84
85
|
def self.config
|
85
86
|
if config?
|
86
|
-
erb = ERB.new(File.read(
|
87
|
+
erb = ERB.new(File.read(config_file_path)).result
|
87
88
|
(YAML.load(erb) || {}).with_indifferent_access
|
88
89
|
else
|
89
90
|
{}
|
@@ -92,7 +93,7 @@ module I18n
|
|
92
93
|
|
93
94
|
# Check if configuration file exist
|
94
95
|
def self.config?
|
95
|
-
File.file?
|
96
|
+
File.file? config_file_path
|
96
97
|
end
|
97
98
|
|
98
99
|
# Convert translations to JSON string and save file.
|
@@ -101,7 +102,7 @@ module I18n
|
|
101
102
|
|
102
103
|
File.open(file, "w+") do |f|
|
103
104
|
f << %(I18n.translations || (I18n.translations = {});\n)
|
104
|
-
translations.each do |locale, translations_for_locale|
|
105
|
+
Utils.strip_keys_with_nil_values(translations).each do |locale, translations_for_locale|
|
105
106
|
f << %(I18n.translations["#{locale}"] = #{translations_for_locale.to_json};\n);
|
106
107
|
end
|
107
108
|
end
|
@@ -111,7 +112,7 @@ module I18n
|
|
111
112
|
result = {}
|
112
113
|
|
113
114
|
[scopes].flatten.each do |scope|
|
114
|
-
deep_merge! result, filter(translations, scope)
|
115
|
+
Utils.deep_merge! result, filter(translations, scope)
|
115
116
|
end
|
116
117
|
|
117
118
|
result
|
@@ -144,12 +145,27 @@ module I18n
|
|
144
145
|
end
|
145
146
|
end
|
146
147
|
|
147
|
-
def self.deep_merge(target, hash) # :nodoc:
|
148
|
-
target.merge(hash, &MERGER)
|
149
|
-
end
|
150
148
|
|
151
|
-
|
152
|
-
|
149
|
+
### Export i18n.js
|
150
|
+
begin
|
151
|
+
# Copy i18n.js
|
152
|
+
def self.export_i18n_js
|
153
|
+
return if export_i18n_js_dir_path.nil?
|
154
|
+
|
155
|
+
FileUtils.mkdir_p(export_i18n_js_dir_path)
|
156
|
+
|
157
|
+
i18n_js_path = File.expand_path('../../../app/assets/javascripts/i18n.js', __FILE__)
|
158
|
+
FileUtils.cp(i18n_js_path, export_i18n_js_dir_path)
|
159
|
+
end
|
160
|
+
def self.export_i18n_js_dir_path
|
161
|
+
return @export_i18n_js_dir_path if defined?(@export_i18n_js_dir_path)
|
162
|
+
|
163
|
+
@export_i18n_js_dir_path = DEFAULT_EXPORT_DIR_PATH
|
164
|
+
end
|
165
|
+
# Setting this to nil would disable i18n.js exporting
|
166
|
+
def self.export_i18n_js_dir_path=(new_path)
|
167
|
+
@export_i18n_js_dir_path = new_path
|
168
|
+
end
|
153
169
|
end
|
154
170
|
end
|
155
171
|
end
|
data/lib/i18n/js/dependencies.rb
CHANGED
@@ -10,6 +10,10 @@ module I18n
|
|
10
10
|
safe_gem_check("rails", "~> 4") && running_rails4?
|
11
11
|
end
|
12
12
|
|
13
|
+
def sprockets_supports_register_preprocessor?
|
14
|
+
defined?(Sprockets) && Sprockets.respond_to?(:register_preprocessor)
|
15
|
+
end
|
16
|
+
|
13
17
|
def rails?
|
14
18
|
rails_available? && running_rails?
|
15
19
|
end
|
data/lib/i18n/js/engine.rb
CHANGED
@@ -3,8 +3,9 @@ require "i18n/js"
|
|
3
3
|
module I18n
|
4
4
|
module JS
|
5
5
|
class Engine < ::Rails::Engine
|
6
|
-
initializer :after => "sprockets.environment" do
|
6
|
+
initializer "i18n-js.register_preprocessor", :after => "sprockets.environment" do
|
7
7
|
next unless JS::Dependencies.using_asset_pipeline?
|
8
|
+
next unless JS::Dependencies.sprockets_supports_register_preprocessor?
|
8
9
|
next unless Rails.configuration.assets.compile
|
9
10
|
|
10
11
|
Rails.application.assets.register_preprocessor "application/javascript", :"i18n-js_dependencies" do |context, source|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module I18n
|
2
|
+
module JS
|
3
|
+
module Utils
|
4
|
+
# deep_merge by Stefan Rusterholz, see <http://www.ruby-forum.com/topic/142809>.
|
5
|
+
MERGER = proc do |key, v1, v2|
|
6
|
+
Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
|
7
|
+
end
|
8
|
+
HASH_NIL_VALUE_CLEANER_PROC = proc do |k, v|
|
9
|
+
v.kind_of?(Hash) ? (v.delete_if(&HASH_NIL_VALUE_CLEANER_PROC); false) : v.nil?
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
def self.strip_keys_with_nil_values(hash)
|
14
|
+
hash.dup.delete_if(&HASH_NIL_VALUE_CLEANER_PROC)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.deep_merge(target_hash, hash) # :nodoc:
|
18
|
+
target_hash.merge(hash, &MERGER)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.deep_merge!(target_hash, hash) # :nodoc:
|
22
|
+
target_hash.merge!(hash, &MERGER)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/i18n/js/version.rb
CHANGED
data/spec/i18n_js_spec.rb
CHANGED
@@ -1,9 +1,25 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe I18n::JS do
|
4
|
+
describe '.config_file_path' do
|
5
|
+
let(:default_path) { I18n::JS::DEFAULT_CONFIG_PATH }
|
6
|
+
let(:new_path) { File.join("tmp", default_path) }
|
7
|
+
|
8
|
+
subject { described_class.config_file_path }
|
9
|
+
|
10
|
+
context "when it is not set" do
|
11
|
+
it { should eq default_path }
|
12
|
+
end
|
13
|
+
context "when it is set already" do
|
14
|
+
before { described_class.config_file_path = new_path }
|
15
|
+
|
16
|
+
it { should eq new_path }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
4
20
|
context "exporting" do
|
5
21
|
before do
|
6
|
-
I18n::JS
|
22
|
+
stub_const('I18n::JS::DEFAULT_EXPORT_DIR_PATH', temp_path)
|
7
23
|
end
|
8
24
|
|
9
25
|
it "exports messages to default path when configuration file doesn't exist" do
|
@@ -65,6 +81,12 @@ describe I18n::JS do
|
|
65
81
|
result["tmp/i18n-js/bits.#{lang}.js"][lang.to_sym].keys.sort.should eql([:date, :number])
|
66
82
|
end
|
67
83
|
end
|
84
|
+
|
85
|
+
it "calls .export_i18n_js" do
|
86
|
+
allow(described_class).to receive(:export_i18n_js)
|
87
|
+
I18n::JS.export
|
88
|
+
expect(described_class).to have_received(:export_i18n_js).once
|
89
|
+
end
|
68
90
|
end
|
69
91
|
|
70
92
|
context "filters" do
|
@@ -133,7 +155,7 @@ describe I18n::JS do
|
|
133
155
|
|
134
156
|
context "general" do
|
135
157
|
it "sets export directory" do
|
136
|
-
I18n::JS.
|
158
|
+
I18n::JS::DEFAULT_EXPORT_DIR_PATH.should eql("public/javascripts")
|
137
159
|
end
|
138
160
|
|
139
161
|
it "sets empty hash as configuration when no file is found" do
|
@@ -149,19 +171,148 @@ describe I18n::JS do
|
|
149
171
|
end
|
150
172
|
end
|
151
173
|
|
174
|
+
|
175
|
+
describe "i18n.js exporting" do
|
176
|
+
describe ".export_i18n_js" do
|
177
|
+
before do
|
178
|
+
allow(FileUtils).to receive(:mkdir_p).and_call_original
|
179
|
+
allow(FileUtils).to receive(:cp).and_call_original
|
180
|
+
|
181
|
+
described_class.stub(:export_i18n_js_dir_path).and_return(export_i18n_js_dir_path)
|
182
|
+
I18n::JS.export_i18n_js
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'when .export_i18n_js_dir_path returns something' do
|
186
|
+
let(:export_i18n_js_dir_path) { temp_path }
|
187
|
+
|
188
|
+
it "does create the folder before copying" do
|
189
|
+
expect(FileUtils).to have_received(:mkdir_p).with(export_i18n_js_dir_path).once
|
190
|
+
end
|
191
|
+
it "does copy the file with FileUtils.cp" do
|
192
|
+
expect(FileUtils).to have_received(:cp).once
|
193
|
+
end
|
194
|
+
it "exports the file" do
|
195
|
+
File.should be_file(File.join(I18n::JS.export_i18n_js_dir_path, "i18n.js"))
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'when .export_i18n_js_dir_path is set to nil' do
|
200
|
+
let(:export_i18n_js_dir_path) { nil }
|
201
|
+
|
202
|
+
it "does NOT create the folder before copying" do
|
203
|
+
expect(FileUtils).to_not have_received(:mkdir_p)
|
204
|
+
end
|
205
|
+
it "does NOT copy the file with FileUtils.cp" do
|
206
|
+
expect(FileUtils).to_not have_received(:cp)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
describe '.export_i18n_js_dir_path' do
|
213
|
+
let(:default_path) { I18n::JS::DEFAULT_EXPORT_DIR_PATH }
|
214
|
+
let(:new_path) { File.join("tmp", default_path) }
|
215
|
+
before { described_class.send(:remove_instance_variable, :@export_i18n_js_dir_path) }
|
216
|
+
|
217
|
+
subject { described_class.export_i18n_js_dir_path }
|
218
|
+
|
219
|
+
context "when it is not set" do
|
220
|
+
it { should eq default_path }
|
221
|
+
end
|
222
|
+
context "when it is set to another path already" do
|
223
|
+
before { described_class.export_i18n_js_dir_path = new_path }
|
224
|
+
|
225
|
+
it { should eq new_path }
|
226
|
+
end
|
227
|
+
context "when it is set to nil already" do
|
228
|
+
before { described_class.export_i18n_js_dir_path = nil }
|
229
|
+
|
230
|
+
it { should be_nil }
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe I18n::JS::Dependencies, ".sprockets_supports_register_preprocessor?" do
|
237
|
+
|
238
|
+
subject { described_class.sprockets_supports_register_preprocessor? }
|
239
|
+
|
240
|
+
context 'when Sprockets is available to register preprocessors' do
|
241
|
+
let!(:sprockets_double) do
|
242
|
+
class_double('Sprockets').as_stubbed_const(register_processor: true).tap do |double|
|
243
|
+
allow(double).to receive(:respond_to?).with(:register_preprocessor).and_return(true)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
it { is_expected.to be_truthy }
|
248
|
+
it 'calls respond_to? with register_preprocessor on Sprockets' do
|
249
|
+
expect(sprockets_double).to receive(:respond_to?).with(:register_preprocessor).and_return(true)
|
250
|
+
subject
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context 'when Sprockets is NOT available to register preprocessors' do
|
255
|
+
let!(:sprockets_double) do
|
256
|
+
class_double('Sprockets').as_stubbed_const(register_processor: true).tap do |double|
|
257
|
+
allow(double).to receive(:respond_to?).with(:register_preprocessor).and_return(false)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
it { is_expected.to be_falsy }
|
262
|
+
it 'calls respond_to? with register_preprocessor on Sprockets' do
|
263
|
+
expect(sprockets_double).to receive(:respond_to?).with(:register_preprocessor).and_return(false)
|
264
|
+
subject
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context 'when Sprockets is missing' do
|
269
|
+
before do
|
270
|
+
hide_const('Sprockets')
|
271
|
+
expect { Sprockets }.to raise_error(NameError)
|
272
|
+
end
|
273
|
+
|
274
|
+
it { is_expected.to be_falsy }
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
describe I18n::JS::Utils do
|
280
|
+
|
281
|
+
describe ".strip_keys_with_nil_values" do
|
282
|
+
subject { described_class.strip_keys_with_nil_values(input_hash) }
|
283
|
+
|
284
|
+
context 'when input_hash does NOT contain nil value' do
|
285
|
+
let(:input_hash) { {a: 1, b: { c: 2 }} }
|
286
|
+
let(:expected_hash) { input_hash }
|
287
|
+
|
288
|
+
it 'returns the original input' do
|
289
|
+
is_expected.to eq expected_hash
|
290
|
+
end
|
291
|
+
end
|
292
|
+
context 'when input_hash does contain nil value' do
|
293
|
+
let(:input_hash) { {a: 1, b: { c: 2, d: nil }, e: { f: nil }} }
|
294
|
+
let(:expected_hash) { {a: 1, b: { c: 2 }, e: {}} }
|
295
|
+
|
296
|
+
it 'returns the original input with nil values removed' do
|
297
|
+
is_expected.to eq expected_hash
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
152
302
|
context "hash merging" do
|
153
303
|
it "performs a deep merge" do
|
154
304
|
target = {:a => {:b => 1}}
|
155
|
-
result =
|
305
|
+
result = described_class.deep_merge(target, {:a => {:c => 2}})
|
156
306
|
|
157
307
|
result[:a].should eql({:b => 1, :c => 2})
|
158
308
|
end
|
159
309
|
|
160
310
|
it "performs a banged deep merge" do
|
161
311
|
target = {:a => {:b => 1}}
|
162
|
-
|
312
|
+
described_class.deep_merge!(target, {:a => {:c => 2}})
|
163
313
|
|
164
314
|
target[:a].should eql({:b => 1, :c => 2})
|
165
315
|
end
|
166
316
|
end
|
317
|
+
|
167
318
|
end
|
@@ -25,4 +25,9 @@ describe("Interpolation", function(){
|
|
25
25
|
expect(I18n.t("inbox", {count: 1})).toEqual("You have 1 message");
|
26
26
|
expect(I18n.t("inbox", {count: 5})).toEqual("You have 5 messages");
|
27
27
|
});
|
28
|
+
|
29
|
+
it("outputs missing placeholder message if interpolation value is missing", function(){
|
30
|
+
actual = I18n.t("greetings.name");
|
31
|
+
expect(actual).toEqual("Hello [missing {{name}} value]!");
|
32
|
+
})
|
28
33
|
});
|
data/spec/js/specs.html
CHANGED
@@ -36,6 +36,7 @@
|
|
36
36
|
<script type="text/javascript" src="pluralization.spec.js"></script>
|
37
37
|
<script type="text/javascript" src="prepare_options.spec.js"></script>
|
38
38
|
<script type="text/javascript" src="translate.spec.js"></script>
|
39
|
+
<script type="text/javascript" src="utility_functions.spec.js"></script>
|
39
40
|
|
40
41
|
<!-- run specs -->
|
41
42
|
<script type="text/javascript">
|
data/spec/js/translate.spec.js
CHANGED
@@ -163,6 +163,15 @@ describe("Translate", function(){
|
|
163
163
|
expect(I18n.t("paid", {price: "$1.35"})).toEqual("You were paid $1.35");
|
164
164
|
});
|
165
165
|
|
166
|
+
it("replaces all occurrences of escaped $", function(){
|
167
|
+
I18n.locale = "en";
|
168
|
+
|
169
|
+
expect(I18n.t("paid_with_vat", {
|
170
|
+
price: "$0.12",
|
171
|
+
vat: "$0.02"}
|
172
|
+
)).toEqual("You were paid $0.12 (incl. VAT $0.02)");
|
173
|
+
});
|
174
|
+
|
166
175
|
it("sets default scope", function(){
|
167
176
|
var options = {scope: "greetings"};
|
168
177
|
expect(I18n.t("stranger", options)).toEqual("Hello stranger!");
|
data/spec/js/translations.js
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
var I18n = require("../../app/assets/javascripts/i18n");
|
2
|
+
|
3
|
+
describe("Utility Functions", function(){
|
4
|
+
beforeEach(function(){
|
5
|
+
I18n.reset();
|
6
|
+
});
|
7
|
+
|
8
|
+
describe("I18n.lookup", function() {
|
9
|
+
it("does not change locale on failed lookup", function(){
|
10
|
+
var fallback_locales = ['fallback1', 'fallback2'];
|
11
|
+
|
12
|
+
I18n.locales['lang'] = fallback_locales.slice();
|
13
|
+
expect(I18n.locales.lang).toEqual(fallback_locales);
|
14
|
+
|
15
|
+
I18n.lookup('anything', {locale: 'lang'})
|
16
|
+
expect(I18n.locales.lang).toEqual(fallback_locales);
|
17
|
+
});
|
18
|
+
|
19
|
+
})
|
20
|
+
});
|
data/spec/spec_helper.rb
CHANGED
@@ -7,8 +7,8 @@ require "i18n/js"
|
|
7
7
|
module Helpers
|
8
8
|
# Set the configuration as the current one
|
9
9
|
def set_config(path)
|
10
|
-
|
11
|
-
I18n::JS.stub(:config? => true, :
|
10
|
+
config_file_path = File.dirname(__FILE__) + "/fixtures/#{path}"
|
11
|
+
I18n::JS.stub(:config? => true, :config_file_path => config_file_path)
|
12
12
|
end
|
13
13
|
|
14
14
|
# Shortcut to I18n::JS.translations
|
@@ -17,7 +17,7 @@ module Helpers
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def file_should_exist(name)
|
20
|
-
file_path = File.join(I18n::JS
|
20
|
+
file_path = File.join(I18n::JS::DEFAULT_EXPORT_DIR_PATH, name)
|
21
21
|
File.should be_file(file_path)
|
22
22
|
end
|
23
23
|
|
metadata
CHANGED
@@ -1,111 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0.
|
4
|
+
version: 3.0.0.rc7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.6'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: appraisal
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activesupport
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '3.0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: pry-meta
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: gem-release
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0.7'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0.7'
|
111
111
|
description: It's a small library to provide the Rails I18n translations on the Javascript.
|
@@ -115,8 +115,8 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
-
- .gitignore
|
119
|
-
- .travis.yml
|
118
|
+
- ".gitignore"
|
119
|
+
- ".travis.yml"
|
120
120
|
- Appraisals
|
121
121
|
- CHANGELOG.md
|
122
122
|
- Gemfile
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- lib/i18n/js/dependencies.rb
|
134
134
|
- lib/i18n/js/engine.rb
|
135
135
|
- lib/i18n/js/middleware.rb
|
136
|
+
- lib/i18n/js/utils.rb
|
136
137
|
- lib/i18n/js/version.rb
|
137
138
|
- lib/rails/generators/i18n/js/config/config_generator.rb
|
138
139
|
- lib/rails/generators/i18n/js/config/templates/i18n-js.yml
|
@@ -168,9 +169,11 @@ files:
|
|
168
169
|
- spec/js/specs.html
|
169
170
|
- spec/js/translate.spec.js
|
170
171
|
- spec/js/translations.js
|
172
|
+
- spec/js/utility_functions.spec.js
|
171
173
|
- spec/spec_helper.rb
|
172
174
|
homepage: http://rubygems.org/gems/i18n-js
|
173
|
-
licenses:
|
175
|
+
licenses:
|
176
|
+
- MIT
|
174
177
|
metadata: {}
|
175
178
|
post_install_message:
|
176
179
|
rdoc_options: []
|
@@ -178,12 +181,12 @@ require_paths:
|
|
178
181
|
- lib
|
179
182
|
required_ruby_version: !ruby/object:Gem::Requirement
|
180
183
|
requirements:
|
181
|
-
- -
|
184
|
+
- - ">="
|
182
185
|
- !ruby/object:Gem::Version
|
183
|
-
version:
|
186
|
+
version: 1.9.3
|
184
187
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
188
|
requirements:
|
186
|
-
- -
|
189
|
+
- - ">"
|
187
190
|
- !ruby/object:Gem::Version
|
188
191
|
version: 1.3.1
|
189
192
|
requirements: []
|
@@ -223,5 +226,6 @@ test_files:
|
|
223
226
|
- spec/js/specs.html
|
224
227
|
- spec/js/translate.spec.js
|
225
228
|
- spec/js/translations.js
|
229
|
+
- spec/js/utility_functions.spec.js
|
226
230
|
- spec/spec_helper.rb
|
227
231
|
has_rdoc:
|