localeapp 0.6.10 → 0.6.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,20 @@
1
1
  # master
2
2
 
3
+ # Version 0.6.12
4
+
5
+ * Fix an error creating the folder for the syncfile
6
+
7
+ # Version 0.6.11 (yanked)
8
+
9
+ * Handle sending fallbacks
10
+ * Create the schronization data file even if the containing folder is
11
+ missing
12
+ * Fix bug where deleting a namespace and then recreating a key inside
13
+ of it wasn't getting added.
14
+ * Normalize keys so that the scope is added to missing translations
15
+ * Throw a Localeapp::MissingApiKey exception when an API key has not
16
+ been set
17
+
3
18
  # Version 0.6.10
4
19
 
5
20
  * Don't send the :default param with a MissingTranslation when not in
@@ -56,6 +56,7 @@ module Localeapp
56
56
 
57
57
  class LocaleappError < StandardError; end
58
58
  class PotentiallyInsecureYaml < LocaleappError; end
59
+ class MissingApiKey < LocaleappError; end
59
60
 
60
61
  class << self
61
62
  # An Localeapp configuration object.
@@ -3,13 +3,25 @@ module I18n::Backend::Base
3
3
 
4
4
  def default(locale, object, subject, options = {})
5
5
  result = default_without_handler(locale, object, subject, options)
6
+
7
+ original_object = object
8
+ object ||= Thread.current[:i18n_default_object]
6
9
  case subject # case is what i18n gem uses here so doing the same
7
- when Array, Symbol
8
- # Do nothing, we only send missing translations with text defaults
9
- else
10
- value = locale == I18n.default_locale ? subject : nil
10
+ when String
11
+ value = locale.to_s == I18n.default_locale.to_s ? subject : nil
11
12
  Localeapp.missing_translations.add(locale, object, value, options)
13
+ when Array
14
+ text_default = subject.detect{|item| item.is_a? String }
15
+ if text_default
16
+ value = locale.to_s == I18n.default_locale.to_s ? text_default : nil
17
+ Localeapp.missing_translations.add(locale, object, value, options)
18
+ end
19
+ when Symbol
20
+ # Do nothing, we only send missing translations with text defaults
12
21
  end
22
+
23
+ # Remember the object because it will be nil after the fallback
24
+ Thread.current[:i18n_default_object] = original_object
13
25
  return result
14
26
  end
15
27
  end
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  module Localeapp
2
4
  module Rails
3
5
  def self.initialize
@@ -36,8 +38,10 @@ module Localeapp
36
38
  end
37
39
 
38
40
  def self.initialize_synchronization_data_file
39
- if !File.exists?(Localeapp.configuration.synchronization_data_file)
40
- File.open(Localeapp.configuration.synchronization_data_file, 'w') do |f|
41
+ sync_file = Localeapp.configuration.synchronization_data_file
42
+ if !File.exists?(sync_file)
43
+ FileUtils.mkdir_p(File.dirname(sync_file))
44
+ File.open(sync_file, 'w') do |f|
41
45
  f.write({:polled_at => Time.now.to_i, :updated_at => Time.now.to_i}.to_yaml)
42
46
  end
43
47
  end
@@ -7,6 +7,7 @@ module Localeapp
7
7
  end
8
8
 
9
9
  def handle_translation_updates
10
+ raise Localeapp::MissingApiKey unless ::Localeapp.configuration.api_key
10
11
  unless ::Localeapp.configuration.polling_disabled?
11
12
  ::Localeapp.log_with_time 'Handling translation updates'
12
13
  if ::Localeapp.poller.needs_polling?
@@ -9,8 +9,10 @@ module Localeapp
9
9
  def post_translation(locale, key, options, value = nil)
10
10
  options ||= {}
11
11
  options.delete(:default)
12
- options.delete(:scope)
13
- translation = { :key => key, :locale => locale, :substitutions => options.keys.sort, :description => value}
12
+ scope = options.delete(:scope)
13
+ normalized_key = I18n.normalize_keys(nil, key, scope).join('.')
14
+
15
+ translation = { :key => normalized_key, :locale => locale, :substitutions => options.keys.sort, :description => value}
14
16
  @data = { :translation => translation }
15
17
  api_call :create_translation,
16
18
  :payload => @data.to_json,
@@ -61,7 +61,10 @@ module Localeapp
61
61
  return if sub_hash.nil?
62
62
  current_key = keys.shift
63
63
  if keys.empty?
64
- sub_hash.delete(current_key)
64
+ # delete key except if key is now used as a namespace for a child_hash
65
+ unless sub_hash[current_key].is_a?(Hash)
66
+ sub_hash.delete(current_key)
67
+ end
65
68
  else
66
69
  child_hash = sub_hash[current_key]
67
70
  unless child_hash.nil?
@@ -1,3 +1,3 @@
1
1
  module Localeapp
2
- VERSION = "0.6.10"
2
+ VERSION = "0.6.12"
3
3
  end
@@ -4,6 +4,10 @@ class Klass
4
4
  include I18n::Backend::Base
5
5
  end
6
6
 
7
+ class I18nWithFallbacks < I18n::Backend::Simple
8
+ include I18n::Backend::Fallbacks
9
+ end
10
+
7
11
  describe I18n::Backend::Base, '#default' do
8
12
  let(:klass) { Klass.new }
9
13
 
@@ -27,16 +31,35 @@ describe I18n::Backend::Base, '#default' do
27
31
  klass.default(:fr, 'foo', 'bar', :baz => 'bam')
28
32
  end
29
33
  end
34
+
35
+ it "adds translations to missing translations when using a string as the locale" do
36
+ allow_sending do
37
+ Localeapp.missing_translations.should_receive(:add).with('en', 'foo', 'bar', :baz => 'bam')
38
+ klass.default('en', 'foo', 'bar', :baz => 'bam')
39
+ end
40
+ end
30
41
  end
31
42
 
32
43
  describe "when subject is an Array" do
33
- it "doesn't send anything to Locale" do
34
- allow_sending do
35
- Localeapp.missing_translations.should_not_receive(:add)
36
- I18n.stub!(:translate) do |subject, _|
37
- subject == :not_missing ? "not missing" : nil
44
+
45
+ describe "and there is a text inside the array" do
46
+ it "add translations to missing translations to send to Locale" do
47
+ allow_sending do
48
+ Localeapp.missing_translations.should_receive(:add).with(:en, 'foo', 'correct default', :baz => 'bam')
49
+ klass.default(:en, 'foo', [:missing, 'correct default'], :baz => 'bam')
50
+ end
51
+ end
52
+ end
53
+
54
+ describe "and there is not a text inside the array" do
55
+ it "doesn't send anything to Locale" do
56
+ allow_sending do
57
+ Localeapp.missing_translations.should_not_receive(:add)
58
+ I18n.stub!(:translate) do |subject, _|
59
+ subject == :not_missing ? "not missing" : nil
60
+ end
61
+ klass.default(:en, 'foo', [:missing, :not_missing], :baz => 'bam')
38
62
  end
39
- klass.default(:en, 'foo', [:missing, :not_missing], :baz => 'bam')
40
63
  end
41
64
  end
42
65
  end
@@ -49,4 +72,13 @@ describe I18n::Backend::Base, '#default' do
49
72
  end
50
73
  end
51
74
  end
75
+
76
+ it "records missing translations when fallbacks are enabled" do
77
+ i18n = I18nWithFallbacks.new
78
+
79
+ with_configuration(:sending_environments => ['my_env'], :environment_name => 'my_env' ) do
80
+ Localeapp.missing_translations.should_receive(:add).with(:en, 'my.object', 'my default', {:default => 'my default'})
81
+ i18n.translate(:en, 'my.object', :default => 'my default')
82
+ end
83
+ end
52
84
  end
@@ -12,7 +12,11 @@ require 'localeapp/rails/controller'
12
12
  describe Localeapp::Rails::Controller, '#handle_translation_updates' do
13
13
  before do
14
14
  TestController.send(:include, Localeapp::Rails::Controller)
15
- with_configuration(:synchronization_data_file => LocaleappSynchronizationData::setup) do
15
+ configuration = {
16
+ :synchronization_data_file => LocaleappSynchronizationData::setup,
17
+ :api_key => "my_key"
18
+ }
19
+ with_configuration(configuration) do
16
20
  @controller = TestController.new
17
21
  end
18
22
  end
@@ -89,6 +93,16 @@ describe Localeapp::Rails::Controller, '#handle_translation_updates' do
89
93
  @controller.handle_translation_updates
90
94
  end
91
95
  end
96
+
97
+ context "when an api_key is missing" do
98
+ before do
99
+ Localeapp.configuration.api_key = nil
100
+ end
101
+
102
+ it "raises an exception" do
103
+ expect { @controller.handle_translation_updates }.to raise_error Localeapp::MissingApiKey
104
+ end
105
+ end
92
106
  end
93
107
 
94
108
  describe Localeapp::Rails::Controller, '#send_missing_translations' do
@@ -7,15 +7,16 @@ describe Localeapp::Sender, "#post_translation(locale, key, options, value = nil
7
7
  end
8
8
  end
9
9
 
10
- it "posts the missing translation data to the backend" do
11
- data = {
12
- :translation => {
13
- :key => "test.key",
14
- :locale => "en",
15
- :substitutions => ['bar', 'foo'],
16
- :description => "test content"
17
- }
18
- }
10
+ let(:response) { double('response', :code => 200) }
11
+ let(:data) { { :translation => {
12
+ :key => "test.key",
13
+ :locale => "en",
14
+ :substitutions => ['bar', 'foo'],
15
+ :description => "test content"
16
+ }}
17
+ }
18
+
19
+ def expect_execute
19
20
  # have to stub RestClient here as FakeWeb doesn't support looking at the post body yet
20
21
  RestClient::Request.should_receive(:execute).with(hash_including(
21
22
  :url => @sender.translations_url,
@@ -23,8 +24,18 @@ describe Localeapp::Sender, "#post_translation(locale, key, options, value = nil
23
24
  :headers => {
24
25
  :x_localeapp_gem_version => Localeapp::VERSION,
25
26
  :content_type => :json },
26
- :method => :post)).and_return(double('response', :code => 200))
27
- @sender.post_translation('en', 'test.key', { 'foo' => 'foo', 'bar' => 'bar', :default => 'default', :scope => 'scope' }, 'test content')
27
+ :method => :post)).and_return(response)
28
+ end
29
+
30
+ it "posts the missing translation data to the backend" do
31
+ expect_execute
32
+ @sender.post_translation('en', 'test.key', { 'foo' => 'foo', 'bar' => 'bar', :default => 'default' }, 'test content')
33
+ end
34
+
35
+ it "normalizes keys sent with a scope" do
36
+ data[:translation][:key] = 'my.custom.scope.test.key'
37
+ expect_execute
38
+ @sender.post_translation('en', 'test.key', { 'foo' => 'foo', 'bar' => 'bar', :scope => 'my.custom.scope' }, 'test content')
28
39
  end
29
40
  end
30
41
 
@@ -89,6 +89,30 @@ describe Localeapp::Updater, ".update(data)" do
89
89
  }
90
90
  end
91
91
 
92
+ it "doesn't delete a namespace having the same name as a previously deleted key" do
93
+ do_update({
94
+ 'translations' => {
95
+ 'az' => {
96
+ 'once_deleted' => {
97
+ 'but_not' => 'anymore'
98
+ }
99
+ }
100
+ },
101
+ 'deleted' => [
102
+ 'once_deleted'
103
+ ],
104
+ 'locales' => ['az']
105
+ })
106
+
107
+ load_yaml('az').should == {
108
+ 'az' => {
109
+ 'once_deleted' => {
110
+ 'but_not' => 'anymore'
111
+ }
112
+ }
113
+ }
114
+ end
115
+
92
116
  it "doesn't create a new yml file if an unknown locale is passed but it has no translations" do
93
117
  do_update({
94
118
  'translations' => {},
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: localeapp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 10
10
- version: 0.6.10
9
+ - 12
10
+ version: 0.6.12
11
11
  platform: ruby
12
12
  authors:
13
13
  - Christopher Dell
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2013-06-25 00:00:00 Z
19
+ date: 2013-09-13 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: i18n