localeapp 0.6.10 → 0.6.12

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