localeapp 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # Version 0.6.3
2
+
3
+ * Pulling translations now completely replaces the contents of the yaml
4
+ files instead of selectively updating certain translations.
5
+
1
6
  # Version 0.6.2
2
7
 
3
8
  * Fix bug updating synchronization files that caused polling_interval to be ignored
@@ -16,8 +16,8 @@ When /^I have a valid project on localeapp\.com but an incorrect api key "([^"]*
16
16
  end
17
17
 
18
18
  When /^I have a translations on localeapp\.com for the project with api key "([^"]*)"$/ do |api_key|
19
- uri = "https://api.localeapp.com/v1/projects/#{api_key}/translations.yml"
20
- body = valid_translation_data.to_yaml
19
+ uri = "https://api.localeapp.com/v1/projects/#{api_key}/translations/all.yml"
20
+ body = valid_export_data.to_yaml
21
21
  add_fake_web_uri(:get, uri, ['200', 'OK'], body)
22
22
  end
23
23
 
@@ -8,7 +8,7 @@ module Localeapp
8
8
  @output.puts ""
9
9
 
10
10
  @output.puts "Fetching translations:"
11
- api_call :translations,
11
+ api_call :export,
12
12
  :success => :update_backend,
13
13
  :failure => :report_failure,
14
14
  :max_connection_attempts => 3
@@ -17,7 +17,7 @@ module Localeapp
17
17
  def update_backend(response)
18
18
  @output.puts "Success!"
19
19
  @output.puts "Updating backend:"
20
- Localeapp.updater.update(Localeapp.load_yaml(response))
20
+ Localeapp.updater.dump(Localeapp.load_yaml(response))
21
21
  @output.puts "Success!"
22
22
  Localeapp.poller.write_synchronization_data!(Time.now.to_i, Time.now.to_i)
23
23
  end
@@ -26,6 +26,17 @@ module Localeapp
26
26
  [:post, translations_url(options)]
27
27
  end
28
28
 
29
+ def export_endpoint(options = {})
30
+ [:get, export_url(options)]
31
+ end
32
+
33
+ def export_url(options = {})
34
+ options[:format] ||= 'yml'
35
+ url = http_scheme.build(base_options.merge(:path => export_path(options[:format])))
36
+ url.query = options[:query].map { |k,v| "#{k}=#{v}" }.join('&') if options[:query]
37
+ url.to_s
38
+ end
39
+
29
40
  def missing_translations_endpoint(options = {})
30
41
  [:post, missing_translations_url(options)]
31
42
  end
@@ -74,6 +85,12 @@ module Localeapp
74
85
  path
75
86
  end
76
87
 
88
+ def export_path(format = nil)
89
+ path = project_path << '/translations/all'
90
+ path << ".#{format}" if format
91
+ path
92
+ end
93
+
77
94
  def missing_translations_path(format = nil)
78
95
  path = project_path << '/translations/missing'
79
96
  path << ".#{format}" if format
@@ -31,6 +31,15 @@ module Localeapp
31
31
  end
32
32
  end
33
33
 
34
+ def dump(data)
35
+ data.each do |locale, translations|
36
+ filename = File.join(Localeapp.configuration.translation_data_directory, "#{locale}.yml")
37
+ atomic_write(filename) do |file|
38
+ file.write generate_yaml({locale => translations})
39
+ end
40
+ end
41
+ end
42
+
34
43
  private
35
44
 
36
45
  def generate_yaml(translations)
@@ -1,3 +1,3 @@
1
1
  module Localeapp
2
- VERSION = "0.6.2"
2
+ VERSION = "0.6.3"
3
3
  end
@@ -10,7 +10,7 @@ describe Localeapp::CLI::Pull, "#execute" do
10
10
  it "makes the api call to the translations endpoint" do
11
11
  with_configuration do
12
12
  @puller.should_receive(:api_call).with(
13
- :translations,
13
+ :export,
14
14
  :success => :update_backend,
15
15
  :failure => :report_failure,
16
16
  :max_connection_attempts => 3
@@ -30,14 +30,14 @@ describe Localeapp::CLI::Pull, "#update_backend(response)" do
30
30
  it "calls the updater" do
31
31
  with_configuration do
32
32
  Localeapp.poller.stub!(:write_synchronization_data!)
33
- Localeapp.updater.should_receive(:update).with(['test data'])
33
+ Localeapp.updater.should_receive(:dump).with(['test data'])
34
34
  @puller.update_backend(@test_data)
35
35
  end
36
36
  end
37
37
 
38
38
  it "writes the synchronization data" do
39
39
  with_configuration do
40
- Localeapp.updater.stub!(:update)
40
+ Localeapp.updater.stub!(:dump)
41
41
  Localeapp.poller.should_receive(:write_synchronization_data!)
42
42
  @puller.update_backend(@test_data)
43
43
  end
@@ -82,6 +82,38 @@ describe Localeapp::Routes do
82
82
  end
83
83
  end
84
84
 
85
+ describe "#export_url" do
86
+ it "it extends the project_url and defaults to yml" do
87
+ with_configuration(@config) do
88
+ @routes.export_url.should == "https://test.host/v1/projects/API_KEY/translations/all.yml"
89
+ end
90
+ end
91
+
92
+ it "adds query parameters on to the url" do
93
+ with_configuration(@config) do
94
+ url = @routes.export_url(:query => {:updated_at => '2011-04-19', :foo => :bar})
95
+ url.should match(/\?.*updated_at=2011-04-19/)
96
+ url.should match(/\?.*foo=bar/)
97
+ end
98
+ end
99
+
100
+ it "can be changed to another content type" do
101
+ with_configuration(@config) do
102
+ @routes.export_url(:format => :json).should == 'https://test.host/v1/projects/API_KEY/translations/all.json'
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "#export_endpoint(options = {})" do
108
+ it "returns :get and the export url for the options" do
109
+ with_configuration(@config) do
110
+ options = { :foo => :bar }
111
+ @routes.should_receive(:export_url).with(options).and_return('url')
112
+ @routes.export_endpoint(options).should == [:get, 'url']
113
+ end
114
+ end
115
+ end
116
+
85
117
  describe "#missing_translations_endpoint(options = {})" do
86
118
  it "returns :post and the missing_translations url for the options" do
87
119
  with_configuration(@config) do
@@ -182,3 +182,65 @@ JA
182
182
  mode.to_s(8)[3, 3].should == "644"
183
183
  end
184
184
  end
185
+
186
+ describe Localeapp::Updater, ".dump(data)" do
187
+ before(:each) do
188
+ @yml_dir = Dir.mktmpdir
189
+ Dir.glob(File.join(File.dirname(__FILE__), '..', 'fixtures', '*.yml')).each { |f| FileUtils.cp f, @yml_dir }
190
+ with_configuration(:translation_data_directory => @yml_dir) do
191
+ @updater = Localeapp::Updater.new
192
+ end
193
+ end
194
+
195
+ after(:each) do
196
+ FileUtils.rm_rf @yml_dir
197
+ end
198
+
199
+ def do_dump(data)
200
+ @updater.dump(data)
201
+ end
202
+
203
+ it "replaces the content of an existing yml file" do
204
+ filepath = File.join(@yml_dir, 'en.yml')
205
+ content = lambda { File.read(filepath) }
206
+ if defined? Psych
207
+ expect { do_dump({'en' => {'updated' => 'content'}}) }.to change(content, :call).to <<-EN
208
+ en:
209
+ updated: content
210
+ EN
211
+ else
212
+ expect { do_dump({'en' => {'updated' => 'content'}}) }.to change(content, :call).to <<-EN
213
+ en:
214
+ updated: content
215
+ EN
216
+ end
217
+ end
218
+
219
+ it "creates a new yml file if an unknown locale is passed" do
220
+ do_dump({'ja' => { 'foo' => 'bar'} })
221
+ if defined? Psych
222
+ File.read(File.join(@yml_dir, 'ja.yml')).should == <<-JA
223
+ ja:
224
+ foo: bar
225
+ JA
226
+ else
227
+ File.read(File.join(@yml_dir, 'ja.yml')).should == <<-JA
228
+ ja:
229
+ foo: bar
230
+ JA
231
+ end
232
+ end
233
+
234
+ it "doesn't change a yml file's permissions" do
235
+ filepath = File.join(@yml_dir, 'en.yml')
236
+ File.chmod(0777, filepath)
237
+ permissions = lambda { File.stat(filepath).mode.to_s(8) }
238
+ expect { do_dump({'en' => { 'foo' => 'bar'} }) }.to_not change(permissions, :call)
239
+ end
240
+
241
+ it "creates new yml files chmodded with 644" do
242
+ do_dump({'ja' => { 'foo' => 'bar'} })
243
+ mode = File.stat(File.join(@yml_dir, 'ja.yml')).mode # octal
244
+ mode.to_s(8)[3, 3].should == "644"
245
+ end
246
+ end
@@ -30,4 +30,14 @@ module LocaleappIntegrationData
30
30
  'locales' => %w{en es}
31
31
  }
32
32
  end
33
+
34
+ def valid_export_data
35
+ { 'en' => {
36
+ 'foo' => {'monkey' => 'hello', 'night' => 'night'}
37
+ },
38
+ 'es' => {
39
+ 'foo' => {'monkey' => 'hola', 'night' => 'noche'}
40
+ }
41
+ }
42
+ end
33
43
  end
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: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 2
10
- version: 0.6.2
9
+ - 3
10
+ version: 0.6.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Christopher Dell
@@ -16,12 +16,13 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2012-10-15 00:00:00 Z
19
+ date: 2012-10-19 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: i18n
23
+ type: :runtime
23
24
  prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
26
  none: false
26
27
  requirements:
27
28
  - - ">="
@@ -30,12 +31,12 @@ dependencies:
30
31
  segments:
31
32
  - 0
32
33
  version: "0"
33
- type: :runtime
34
- version_requirements: *id001
34
+ requirement: *id001
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: json
37
+ type: :runtime
37
38
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
40
  none: false
40
41
  requirements:
41
42
  - - ">="
@@ -44,12 +45,12 @@ dependencies:
44
45
  segments:
45
46
  - 0
46
47
  version: "0"
47
- type: :runtime
48
- version_requirements: *id002
48
+ requirement: *id002
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rest-client
51
+ type: :runtime
51
52
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
53
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
54
  none: false
54
55
  requirements:
55
56
  - - ">="
@@ -58,12 +59,12 @@ dependencies:
58
59
  segments:
59
60
  - 0
60
61
  version: "0"
61
- type: :runtime
62
- version_requirements: *id003
62
+ requirement: *id003
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: ya2yaml
65
+ type: :runtime
65
66
  prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
67
+ version_requirements: &id004 !ruby/object:Gem::Requirement
67
68
  none: false
68
69
  requirements:
69
70
  - - ">="
@@ -72,12 +73,12 @@ dependencies:
72
73
  segments:
73
74
  - 0
74
75
  version: "0"
75
- type: :runtime
76
- version_requirements: *id004
76
+ requirement: *id004
77
77
  - !ruby/object:Gem::Dependency
78
78
  name: gli
79
+ type: :runtime
79
80
  prerelease: false
80
- requirement: &id005 !ruby/object:Gem::Requirement
81
+ version_requirements: &id005 !ruby/object:Gem::Requirement
81
82
  none: false
82
83
  requirements:
83
84
  - - ">="
@@ -86,12 +87,12 @@ dependencies:
86
87
  segments:
87
88
  - 0
88
89
  version: "0"
89
- type: :runtime
90
- version_requirements: *id005
90
+ requirement: *id005
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rake
93
+ type: :development
93
94
  prerelease: false
94
- requirement: &id006 !ruby/object:Gem::Requirement
95
+ version_requirements: &id006 !ruby/object:Gem::Requirement
95
96
  none: false
96
97
  requirements:
97
98
  - - ">="
@@ -100,12 +101,12 @@ dependencies:
100
101
  segments:
101
102
  - 0
102
103
  version: "0"
103
- type: :development
104
- version_requirements: *id006
104
+ requirement: *id006
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: rspec
107
+ type: :development
107
108
  prerelease: false
108
- requirement: &id007 !ruby/object:Gem::Requirement
109
+ version_requirements: &id007 !ruby/object:Gem::Requirement
109
110
  none: false
110
111
  requirements:
111
112
  - - "="
@@ -116,12 +117,12 @@ dependencies:
116
117
  - 11
117
118
  - 0
118
119
  version: 2.11.0
119
- type: :development
120
- version_requirements: *id007
120
+ requirement: *id007
121
121
  - !ruby/object:Gem::Dependency
122
122
  name: yard
123
+ type: :development
123
124
  prerelease: false
124
- requirement: &id008 !ruby/object:Gem::Requirement
125
+ version_requirements: &id008 !ruby/object:Gem::Requirement
125
126
  none: false
126
127
  requirements:
127
128
  - - "="
@@ -132,12 +133,12 @@ dependencies:
132
133
  - 6
133
134
  - 7
134
135
  version: 0.6.7
135
- type: :development
136
- version_requirements: *id008
136
+ requirement: *id008
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: RedCloth
139
+ type: :development
139
140
  prerelease: false
140
- requirement: &id009 !ruby/object:Gem::Requirement
141
+ version_requirements: &id009 !ruby/object:Gem::Requirement
141
142
  none: false
142
143
  requirements:
143
144
  - - "="
@@ -148,12 +149,12 @@ dependencies:
148
149
  - 2
149
150
  - 9
150
151
  version: 4.2.9
151
- type: :development
152
- version_requirements: *id009
152
+ requirement: *id009
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: aruba
155
+ type: :development
155
156
  prerelease: false
156
- requirement: &id010 !ruby/object:Gem::Requirement
157
+ version_requirements: &id010 !ruby/object:Gem::Requirement
157
158
  none: false
158
159
  requirements:
159
160
  - - "="
@@ -164,12 +165,12 @@ dependencies:
164
165
  - 4
165
166
  - 11
166
167
  version: 0.4.11
167
- type: :development
168
- version_requirements: *id010
168
+ requirement: *id010
169
169
  - !ruby/object:Gem::Dependency
170
170
  name: fakeweb
171
+ type: :development
171
172
  prerelease: false
172
- requirement: &id011 !ruby/object:Gem::Requirement
173
+ version_requirements: &id011 !ruby/object:Gem::Requirement
173
174
  none: false
174
175
  requirements:
175
176
  - - "="
@@ -180,8 +181,7 @@ dependencies:
180
181
  - 3
181
182
  - 0
182
183
  version: 1.3.0
183
- type: :development
184
- version_requirements: *id011
184
+ requirement: *id011
185
185
  description: Synchronizes i18n translation keys and content with localeapp.com so you don't have to manage translations by hand.
186
186
  email:
187
187
  - chris@tigrish.com
@@ -300,7 +300,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
300
300
  requirements: []
301
301
 
302
302
  rubyforge_project: localeapp
303
- rubygems_version: 1.8.24
303
+ rubygems_version: 1.8.6
304
304
  signing_key:
305
305
  specification_version: 3
306
306
  summary: Easy i18n translation management with localeapp.com