i18nliner 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,16 +2,6 @@
2
2
 
3
3
  [<img src="https://secure.travis-ci.org/jenseng/i18nliner.png" />](http://travis-ci.org/jenseng/i18nliner)
4
4
 
5
- yay readme-driven development!
6
-
7
- ## TODO
8
-
9
- * rake tasks
10
- * diff
11
- * import
12
-
13
- ====
14
-
15
5
  I18nliner is I18n made simple.
16
6
 
17
7
  No .yml files. Inline defaults. Optional keys. Inferred interpolation values.
@@ -87,8 +77,9 @@ translation? I18nliner makes keys optional, so you can just do this:
87
77
  I18n.t "My Account"
88
78
  ```
89
79
 
90
- I18nliner will create a [unique key](CONFIG.md) based on the translation (e.g.
91
- `:my_account`), so you don't have to.
80
+ I18nliner will create a unique key based on the translation (e.g.
81
+ `:my_account`), so you don't have to. See `I18nliner.inferred_key_format` for
82
+ more information.
92
83
 
93
84
  This can actually be a **good thing**, because when the `en` changes, the key
94
85
  changes, which means you know you need to get it retranslated (instead of
@@ -104,7 +95,7 @@ value. So this:
104
95
 
105
96
  ```erb
106
97
  <p>
107
- <%= t "Hello, %{user}. This request was a %{request_method}.",
98
+ <%= t "Hello, %{user}. This request was a %{request_method}.",
108
99
  user: @user.name,
109
100
  request_method: request.method
110
101
  %>
@@ -237,7 +228,7 @@ before it hits ERB:
237
228
  ```
238
229
 
239
230
  In other words, it will infer wrappers from your (balanced) markup and
240
- [`link_to` calls](INFERRED_WRAPPERS.md), and will create placeholders for any
231
+ `link_to` calls, and will create placeholders for any
241
232
  other (inline) ERB expressions. ERB statements (e.g.
242
233
  `<% if some_condition %>...`) and block expressions (e.g.
243
234
  `<%= form_for @person do %>...`) are *not* supported within a block
@@ -305,27 +296,16 @@ Does an i18nliner:check, and then extracts all default translations from your
305
296
  codebase, merges them with any other ones (from rails or pre-existing .yml
306
297
  files), and outputs them to `config/locales/generated/en.yml`.
307
298
 
308
- ### Dynamic Translations
299
+ #### Dynamic Translations
309
300
 
310
301
  Note that check and dump commands require all translation keys and
311
302
  defaults to be literals. This is because it reads your code, it doesn't
312
303
  run it. If you know what you are doing and want to pass in a variable or
313
- other expression, you can use the `t!` (or `translate!`) command. It works
304
+ other expression, you can use the `t!` (or `translate!`) method. It works
314
305
  the same as `t` at runtime, but signals to the extractor that it shouldn't
315
306
  complain. You should only do this if you are sure that the specified
316
307
  key/string is extracted elsewhere or already in your yml.
317
308
 
318
- ### i18nliner:diff
319
-
320
- Does an i18nliner:dump and creates a diff from a previous one (path or git
321
- commit hash). This is useful if you only want to see what has changed since a
322
- previous release of your app.
323
-
324
- ### i18nliner:import
325
-
326
- Imports a translated yml file. Ensures that all placeholders and wrappers are
327
- present.
328
-
329
309
  #### .i18nignore and more
330
310
 
331
311
  By default, the check and dump tasks will look for inline translations in any
@@ -14,8 +14,9 @@ module I18nliner
14
14
  end
15
15
 
16
16
  def self.manual_translations
17
+ I18n.t(:foo) # ensure backend is initialized
17
18
  # TODO: support additional backends
18
- I18n.backend.send(:translations)
19
+ I18n.backend.send(:translations)[I18n.default_locale]
19
20
  end
20
21
 
21
22
  def self.look_up(key)
@@ -44,4 +45,5 @@ module I18nliner
44
45
  setting :inferred_key_format, :underscored_crc32
45
46
  setting :infer_interpolation_values, true
46
47
  setting :base_path, "./"
48
+ setting :underscored_key_length, 50
47
49
  end
@@ -35,7 +35,7 @@ module I18nliner
35
35
  key.downcase!
36
36
  key.gsub!(/[^a-z0-9_]+/, '_')
37
37
  key.gsub!(/\A_|_\z/, '')
38
- key[0..50]
38
+ key[0...I18nliner.underscored_key_length]
39
39
  end
40
40
 
41
41
  def keyify_underscored_crc32(string)
@@ -16,7 +16,7 @@ module I18nliner
16
16
  def run
17
17
  FileUtils.mkdir_p File.dirname(yml_file)
18
18
  File.open(yml_file, "w") do |file|
19
- file.write({I18n.default_locale.to_s => @translations}.ya2yaml(:syck_compatible => true))
19
+ file.write({I18n.default_locale.to_s => @translations.expand_keys}.ya2yaml(:syck_compatible => true))
20
20
  end
21
21
  puts "Wrote default translations to #{yml_file}" unless @options[:silent]
22
22
  end
@@ -0,0 +1,30 @@
1
+ require 'i18nliner/commands/generic_command'
2
+ require 'i18nliner/extractors/translation_hash'
3
+ require 'active_support/core_ext/enumerable'
4
+ Dir[File.join(File.dirname(__FILE__), "../processors/*.rb")].each do |file|
5
+ require "i18nliner/processors/#{File.basename(file)}"
6
+ end
7
+
8
+ module I18nliner
9
+ module Commands
10
+ class Import < GenericCommand
11
+ attr_reader :translations, :errors
12
+
13
+ def initialize(options)
14
+ super
15
+ end
16
+
17
+ def success?
18
+ end
19
+
20
+ def print_summary
21
+ end
22
+
23
+ def run
24
+ print_summary unless @options[:silent]
25
+ success?
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -20,7 +20,7 @@ module I18nliner
20
20
 
21
21
  # can't super this one yet :-/
22
22
  def interpolate_hash_with_html_safety(string, values)
23
- if string.html_safe? || values.values.any?(&:html_safe?)
23
+ if string.html_safe? || values.values.any?{ |v| v.is_a?(ActiveSupport::SafeBuffer) }
24
24
  string = ERB::Util.h(string) unless string.html_safe?
25
25
  values.each do |key, value|
26
26
  values[key] = ERB::Util.h(value) unless value.html_safe?
@@ -4,14 +4,25 @@ module I18nliner
4
4
  attr_accessor :line
5
5
 
6
6
  def self.new(hash = {})
7
- hash.is_a?(self) ? hash : super().replace(hash)
7
+ hash.is_a?(self) ? hash : super().replace(flatten(hash))
8
8
  end
9
-
9
+
10
+ def self.flatten(hash, result = {}, prefix = "")
11
+ hash.each do |key, value|
12
+ if value.is_a?(Hash)
13
+ flatten(value, result, "#{prefix}#{key}.")
14
+ else
15
+ result["#{prefix}#{key}"] = value
16
+ end
17
+ end
18
+ result
19
+ end
20
+
10
21
  def initialize(*args)
11
22
  super
12
23
  @total_size = 0
13
24
  end
14
-
25
+
15
26
  def []=(key, value)
16
27
  parts = key.split('.')
17
28
  leaf = parts.pop
@@ -28,7 +39,7 @@ module I18nliner
28
39
  hash = hash[part]
29
40
  end
30
41
  if hash[leaf]
31
- if hash[leaf] != default
42
+ if hash[leaf] != value
32
43
  if hash[leaf].is_a?(Hash)
33
44
  raise KeyAsScopeError.new(@line, key)
34
45
  else
@@ -40,6 +51,16 @@ module I18nliner
40
51
  hash.store(leaf, value)
41
52
  end
42
53
  end
54
+
55
+ def expand_keys
56
+ result = {}
57
+ each do |key, value|
58
+ parts = key.split(".")
59
+ last = parts.pop
60
+ parts.inject(result){ |h, k2| h[k2] ||= {}}[last] = value
61
+ end
62
+ result
63
+ end
43
64
  end
44
65
  end
45
66
  end
@@ -10,6 +10,7 @@ describe I18nliner::Commands::Check do
10
10
  end
11
11
 
12
12
  it "should find errors" do
13
+ allow(I18nliner).to receive(:manual_translations).and_return({})
13
14
  checker = I18nliner::Commands::Check.new({:silent => true})
14
15
  checker.check_files
15
16
  checker.translations.values.should == ["welcome, %{name}", "Hello World", "*This* is a test, %{user}"]
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  require 'i18nliner/commands/dump'
3
+ require 'i18nliner/extractors/translation_hash'
3
4
  require 'tmpdir'
4
5
 
5
6
  describe I18nliner::Commands::Dump do
@@ -14,7 +15,8 @@ describe I18nliner::Commands::Dump do
14
15
  end
15
16
 
16
17
  it "should dump translations in utf8" do
17
- dumper = I18nliner::Commands::Dump.new({:silent => true, :translations => {'i18n' => "Iñtërnâtiônàlizætiøn"}})
18
+ translations = I18nliner::Extractors::TranslationHash.new('i18n' => "Iñtërnâtiônàlizætiøn")
19
+ dumper = I18nliner::Commands::Dump.new({:silent => true, :translations => translations})
18
20
  dumper.run
19
21
  File.read(dumper.yml_file).gsub(/\s+$/, '').should == <<-YML.strip_heredoc.strip
20
22
  ---
@@ -60,12 +60,19 @@ describe I18nliner::Extensions::Core do
60
60
  result.should be_html_safe
61
61
  end
62
62
 
63
- it "should html-escape the string and other values if any value is html-safe" do
63
+ it "should html-escape the string and other values if any value is html-safe strings" do
64
64
  markup = "<input>"
65
65
  result = i18n.interpolate_hash("type %{input} & you get this: %{output}", :input => markup, :output => markup.html_safe)
66
66
  result.should == "type &lt;input&gt; &amp; you get this: <input>"
67
67
  result.should be_html_safe
68
68
  end
69
+
70
+ it "should not html-escape the string if the html-safe values are not strings" do
71
+ markup = "<input>"
72
+ result = i18n.interpolate_hash("my favorite number is %{number} & my favorite color is %{color}", :number => 1, :color => "red")
73
+ result.should == "my favorite number is 1 & my favorite color is red"
74
+ result.should_not be_html_safe
75
+ end
69
76
  end
70
77
  end
71
78
 
@@ -0,0 +1,38 @@
1
+ require 'i18nliner/errors'
2
+ require 'i18nliner/extractors/translation_hash'
3
+
4
+ describe I18nliner::Extractors::TranslationHash do
5
+
6
+ describe "#[]=" do
7
+ let(:hash) { I18nliner::Extractors::TranslationHash.new }
8
+
9
+ it "should accept identical key/values" do
10
+ expect {
11
+ hash["foo"] = "Foo"
12
+ hash["foo"] = "Foo"
13
+ }.to_not raise_error
14
+ hash.should == {"foo" => "Foo"}
15
+ end
16
+
17
+ it "should reject mismatched values" do
18
+ expect {
19
+ hash["foo"] = "Foo"
20
+ hash["foo"] = "Bar"
21
+ }.to raise_error(I18nliner::KeyInUseError)
22
+ end
23
+
24
+ it "should not let you use a key as a scope" do
25
+ expect {
26
+ hash["foo"] = "Foo"
27
+ hash["foo.bar"] = "Bar"
28
+ }.to raise_error(I18nliner::KeyAsScopeError)
29
+ end
30
+
31
+ it "should not let you use a scope as a key" do
32
+ expect {
33
+ hash["foo.bar"] = "Bar"
34
+ hash["foo"] = "Foo"
35
+ }.to raise_error(I18nliner::KeyAsScopeError)
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18nliner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-29 00:00:00.000000000 Z
12
+ date: 2014-06-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -205,6 +205,7 @@ files:
205
205
  - lib/i18nliner/commands/color_formatter.rb
206
206
  - lib/i18nliner/commands/dump.rb
207
207
  - lib/i18nliner/commands/generic_command.rb
208
+ - lib/i18nliner/commands/import.rb
208
209
  - lib/i18nliner/errors.rb
209
210
  - lib/i18nliner/erubis.rb
210
211
  - lib/i18nliner/extensions/controller.rb
@@ -233,6 +234,7 @@ files:
233
234
  - spec/extensions/view_spec.rb
234
235
  - spec/extractors/ruby_extractor_spec.rb
235
236
  - spec/extractors/translate_call_spec.rb
237
+ - spec/extractors/translation_hash_spec.rb
236
238
  - spec/fixtures/app/models/invalid.rb
237
239
  - spec/fixtures/app/models/valid.rb
238
240
  - spec/pre_processors/erb_pre_processor_spec.rb
@@ -257,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
259
  version: 1.3.5
258
260
  requirements: []
259
261
  rubyforge_project:
260
- rubygems_version: 1.8.25
262
+ rubygems_version: 1.8.23
261
263
  signing_key:
262
264
  specification_version: 3
263
265
  summary: I18n made simple