twine 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/twine/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Twine
2
- VERSION = '0.8.1'
2
+ VERSION = '0.9.0'
3
3
  end
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,2 @@
1
+ Üß`
2
+ da
data/test/test_cli.rb CHANGED
@@ -211,7 +211,7 @@ class CLITestCase < TwineTestCase
211
211
 
212
212
  def test_default_options
213
213
  parse_with ''
214
- expected = {command: 'validate-strings-file', strings_file: 'input.txt', include: "all"}
214
+ expected = {command: 'validate-strings-file', strings_file: 'input.txt', include: :all}
215
215
  assert_equal expected, @options
216
216
  end
217
217
 
@@ -266,29 +266,17 @@ class CLITestCase < TwineTestCase
266
266
  end
267
267
 
268
268
  def test_format
269
- random_format = Twine::Formatters.formatters.sample.format_name
269
+ random_format = Twine::Formatters.formatters.sample.format_name.downcase
270
270
  parse_with "--format #{random_format}"
271
271
  assert_equal random_format, @options[:format]
272
272
  end
273
273
 
274
- def test_format_ignores_case
275
- random_format = Twine::Formatters.formatters.sample.format_name
276
- parse_with "--format #{random_format.upcase}"
277
- assert_equal random_format, @options[:format]
278
- end
279
-
280
274
  def test_include
281
- random_set = ['all', 'translated', 'untranslated'].sample
275
+ random_set = [:all, :translated, :untranslated].sample
282
276
  parse_with "--include #{random_set}"
283
277
  assert_equal random_set, @options[:include]
284
278
  end
285
279
 
286
- def test_include_ignores_case
287
- random_set = ['all', 'translated', 'untranslated'].sample
288
- parse_with "--include #{random_set.upcase}"
289
- assert_equal random_set, @options[:include]
290
- end
291
-
292
280
  def test_output_path
293
281
  parse_with "--output-file #{@output_path}"
294
282
  assert_equal @output_path, @options[:output_path]
@@ -5,7 +5,7 @@ class TestConsumeLocDrop < CommandTestCase
5
5
  super
6
6
 
7
7
  options = {}
8
- options[:input_path] = fixture 'consume_loc_drop.zip'
8
+ options[:input_path] = fixture_path 'consume_loc_drop.zip'
9
9
  options[:output_path] = @output_path
10
10
  options[:format] = 'apple'
11
11
 
@@ -14,31 +14,31 @@ class TestConsumeStringFile < CommandTestCase
14
14
  Twine::Runner.new(options, @strings)
15
15
  end
16
16
 
17
- def prepare_mock_read_file_formatter(formatter_class)
17
+ def prepare_mock_read_formatter(formatter_class)
18
18
  formatter = prepare_mock_formatter(formatter_class)
19
- formatter.expects(:read_file)
19
+ formatter.expects(:read)
20
20
  end
21
21
 
22
22
  def test_deducts_android_format_from_output_path
23
- prepare_mock_read_file_formatter Twine::Formatters::Android
23
+ prepare_mock_read_formatter Twine::Formatters::Android
24
24
 
25
25
  new_runner('fr', 'fr.xml').consume_string_file
26
26
  end
27
27
 
28
28
  def test_deducts_apple_format_from_output_path
29
- prepare_mock_read_file_formatter Twine::Formatters::Apple
29
+ prepare_mock_read_formatter Twine::Formatters::Apple
30
30
 
31
31
  new_runner('fr', 'fr.strings').consume_string_file
32
32
  end
33
33
 
34
34
  def test_deducts_jquery_format_from_output_path
35
- prepare_mock_read_file_formatter Twine::Formatters::JQuery
35
+ prepare_mock_read_formatter Twine::Formatters::JQuery
36
36
 
37
37
  new_runner('fr', 'fr.json').consume_string_file
38
38
  end
39
39
 
40
40
  def test_deducts_gettext_format_from_output_path
41
- prepare_mock_read_file_formatter Twine::Formatters::Gettext
41
+ prepare_mock_read_formatter Twine::Formatters::Gettext
42
42
 
43
43
  new_runner('fr', 'fr.po').consume_string_file
44
44
  end
@@ -46,8 +46,74 @@ class TestConsumeStringFile < CommandTestCase
46
46
  def test_deducts_language_from_input_path
47
47
  random_language = KNOWN_LANGUAGES.sample
48
48
  formatter = prepare_mock_formatter Twine::Formatters::Android
49
- formatter.expects(:read_file).with(anything, random_language)
49
+ formatter.expects(:read).with(anything, random_language)
50
50
 
51
51
  new_runner(nil, "#{random_language}.xml").consume_string_file
52
52
  end
53
+
54
+ class TestEncodings < CommandTestCase
55
+ class DummyFormatter < Twine::Formatters::Abstract
56
+ attr_reader :content
57
+
58
+ def extension
59
+ '.dummy'
60
+ end
61
+
62
+ def format_name
63
+ 'dummy'
64
+ end
65
+
66
+ def read(io, lang)
67
+ @content = io.read
68
+ end
69
+ end
70
+
71
+ def new_runner(input_path, encoding = nil)
72
+ options = {}
73
+ options[:output_path] = @output_path
74
+ options[:input_path] = input_path
75
+ options[:encoding] = encoding if encoding
76
+ options[:languages] = 'en'
77
+
78
+ @strings = Twine::StringsFile.new
79
+ @strings.language_codes.concat KNOWN_LANGUAGES
80
+
81
+ Twine::Runner.new(options, @strings)
82
+ end
83
+
84
+ def setup
85
+ super
86
+ @expected_content = "Üß`\nda\n"
87
+ end
88
+
89
+ def test_reads_utf8
90
+ formatter = prepare_mock_formatter DummyFormatter
91
+ new_runner(fixture_path('enc_utf8.dummy')).consume_string_file
92
+ assert_equal @expected_content, formatter.content
93
+ end
94
+
95
+ def test_reads_utf16le_bom
96
+ formatter = prepare_mock_formatter DummyFormatter
97
+ new_runner(fixture_path('enc_utf16le_bom.dummy')).consume_string_file
98
+ assert_equal @expected_content, formatter.content
99
+ end
100
+
101
+ def test_reads_utf16be_bom
102
+ formatter = prepare_mock_formatter DummyFormatter
103
+ new_runner(fixture_path('enc_utf16be_bom.dummy')).consume_string_file
104
+ assert_equal @expected_content, formatter.content
105
+ end
106
+
107
+ def test_reads_utf16le
108
+ formatter = prepare_mock_formatter DummyFormatter
109
+ new_runner(fixture_path('enc_utf16le.dummy'), 'UTF-16LE').consume_string_file
110
+ assert_equal @expected_content, formatter.content
111
+ end
112
+
113
+ def test_reads_utf16be
114
+ formatter = prepare_mock_formatter DummyFormatter
115
+ new_runner(fixture_path('enc_utf16be.dummy'), 'UTF-16BE').consume_string_file
116
+ assert_equal @expected_content, formatter.content
117
+ end
118
+ end
53
119
  end
@@ -41,8 +41,8 @@ class TestAndroidFormatter < FormatterTest
41
41
  super Twine::Formatters::Android
42
42
  end
43
43
 
44
- def test_read_file_format
45
- @formatter.read_file fixture('formatter_android.xml'), 'en'
44
+ def test_read_format
45
+ @formatter.read content_io('formatter_android.xml'), 'en'
46
46
 
47
47
  assert_file_contents_read_correctly
48
48
  end
@@ -67,11 +67,10 @@ class TestAndroidFormatter < FormatterTest
67
67
  assert_equal '@value', @strings.strings_map['key1'].translations['en']
68
68
  end
69
69
 
70
- def test_write_file_output_format
70
+ def test_format_file
71
71
  formatter = Twine::Formatters::Android.new
72
72
  formatter.strings = @twine_file
73
- formatter.write_file @output_path, 'en'
74
- assert_equal content('formatter_android.xml'), output_content
73
+ assert_equal content('formatter_android.xml'), formatter.format_file('en')
75
74
  end
76
75
 
77
76
  def test_format_key_with_space
@@ -100,6 +99,31 @@ class TestAndroidFormatter < FormatterTest
100
99
  identifier = '@android:string/cancel'
101
100
  assert_equal identifier, @formatter.format_value(identifier)
102
101
  end
102
+
103
+ def test_deducts_language_from_resource_folder
104
+ language = %w(en de fr).sample
105
+ assert_equal language, @formatter.determine_language_given_path("res/values-#{language}")
106
+ end
107
+
108
+ def test_deducts_language_and_region_from_resource_folder
109
+ assert_equal 'de-AT', @formatter.determine_language_given_path("res/values-de-rAT")
110
+ end
111
+
112
+ def test_maps_laguage_deducted_from_resource_folder
113
+ assert_equal 'zh-Hans', @formatter.determine_language_given_path("res/values-zh-rCN")
114
+ end
115
+
116
+ def test_does_not_deduct_language_from_device_capability_resource_folder
117
+ assert_nil @formatter.determine_language_given_path('res/values-w820dp')
118
+ end
119
+
120
+ def test_output_path_is_prefixed
121
+ assert_equal 'values-en', @formatter.output_path_for_language('en')
122
+ end
123
+
124
+ def test_output_path_language_mappings
125
+ assert_equal 'values-zh-rCN', @formatter.output_path_for_language('zh-Hans')
126
+ end
103
127
  end
104
128
 
105
129
  class TestAppleFormatter < FormatterTest
@@ -107,17 +131,56 @@ class TestAppleFormatter < FormatterTest
107
131
  super Twine::Formatters::Apple
108
132
  end
109
133
 
110
- def test_read_file_format
111
- @formatter.read_file fixture('formatter_apple.strings'), 'en'
134
+ def test_read_format
135
+ @formatter.read content_io('formatter_apple.strings'), 'en'
112
136
 
113
137
  assert_file_contents_read_correctly
114
138
  end
115
139
 
116
- def test_write_file_output_format
140
+ def test_reads_quoted_keys
141
+ @formatter.read StringIO.new('"key" = "value"'), 'en'
142
+ assert_equal 'value', @strings.strings_map['key'].translations['en']
143
+ end
144
+
145
+ def test_reads_unquoted_keys
146
+ @formatter.read StringIO.new('key = "value"'), 'en'
147
+ assert_equal 'value', @strings.strings_map['key'].translations['en']
148
+ end
149
+
150
+ def test_ignores_leading_whitespace_before_quoted_keys
151
+ @formatter.read StringIO.new("\t \"key\" = \"value\""), 'en'
152
+ assert_equal 'value', @strings.strings_map['key'].translations['en']
153
+ end
154
+
155
+ def test_ignores_leading_whitespace_before_unquoted_keys
156
+ @formatter.read StringIO.new("\t key = \"value\""), 'en'
157
+ assert_equal 'value', @strings.strings_map['key'].translations['en']
158
+ end
159
+
160
+ def test_allows_quotes_in_quoted_keys
161
+ @formatter.read StringIO.new('"ke\"y" = "value"'), 'en'
162
+ assert_equal 'value', @strings.strings_map['ke"y'].translations['en']
163
+ end
164
+
165
+ def test_does_not_allow_quotes_in_quoted_keys
166
+ @formatter.read StringIO.new('ke"y = "value"'), 'en'
167
+ assert_nil @strings.strings_map['key']
168
+ end
169
+
170
+ def test_allows_equal_signs_in_quoted_keys
171
+ @formatter.read StringIO.new('"k=ey" = "value"'), 'en'
172
+ assert_equal 'value', @strings.strings_map['k=ey'].translations['en']
173
+ end
174
+
175
+ def test_does_not_allow_equal_signs_in_unquoted_keys
176
+ @formatter.read StringIO.new('k=ey = "value"'), 'en'
177
+ assert_nil @strings.strings_map['key']
178
+ end
179
+
180
+ def test_format_file
117
181
  formatter = Twine::Formatters::Apple.new
118
182
  formatter.strings = @twine_file
119
- formatter.write_file @output_path, 'en'
120
- assert_equal content('formatter_apple.strings'), output_content
183
+ assert_equal content('formatter_apple.strings'), formatter.format_file('en')
121
184
  end
122
185
 
123
186
  def test_format_key_with_space
@@ -139,17 +202,16 @@ class TestJQueryFormatter < FormatterTest
139
202
  super Twine::Formatters::JQuery
140
203
  end
141
204
 
142
- def test_read_file_format
143
- @formatter.read_file fixture('formatter_jquery.json'), 'en'
205
+ def test_read_format
206
+ @formatter.read content_io('formatter_jquery.json'), 'en'
144
207
 
145
208
  assert_translations_read_correctly
146
209
  end
147
210
 
148
- def test_write_file_output_format
211
+ def test_format_file
149
212
  formatter = Twine::Formatters::JQuery.new
150
213
  formatter.strings = @twine_file
151
- formatter.write_file @output_path, 'en'
152
- assert_equal content('formatter_jquery.json'), output_content
214
+ assert_equal content('formatter_jquery.json'), formatter.format_file('en')
153
215
  end
154
216
 
155
217
  def test_format_value_with_newline
@@ -163,23 +225,22 @@ class TestGettextFormatter < FormatterTest
163
225
  super Twine::Formatters::Gettext
164
226
  end
165
227
 
166
- def test_read_file_format
167
- @formatter.read_file fixture('formatter_gettext.po'), 'en'
228
+ def test_read_format
229
+ @formatter.read content_io('formatter_gettext.po'), 'en'
168
230
 
169
231
  assert_file_contents_read_correctly
170
232
  end
171
233
 
172
- def test_read_file_with_multiple_line_value
173
- @formatter.read_file fixture('gettext_multiline.po'), 'en'
234
+ def test_read_with_multiple_line_value
235
+ @formatter.read content_io('gettext_multiline.po'), 'en'
174
236
 
175
237
  assert_equal 'multiline\nstring', @strings.strings_map['key1'].translations['en']
176
238
  end
177
239
 
178
- def test_write_file_output_format
240
+ def test_format_file
179
241
  formatter = Twine::Formatters::Gettext.new
180
242
  formatter.strings = @twine_file
181
- formatter.write_file @output_path, 'en'
182
- assert_equal content('formatter_gettext.po'), output_content
243
+ assert_equal content('formatter_gettext.po'), formatter.format_file('en')
183
244
  end
184
245
 
185
246
  end
@@ -190,18 +251,17 @@ class TestTizenFormatter < FormatterTest
190
251
  super Twine::Formatters::Tizen
191
252
  end
192
253
 
193
- def test_read_file_format
194
- skip 'the current implementation of Tizen formatter does not support read_file'
195
- @formatter.read_file fixture('formatter_tizen.xml'), 'en'
254
+ def test_read_format
255
+ skip 'the current implementation of Tizen formatter does not support reading'
256
+ @formatter.read content_io('formatter_tizen.xml'), 'en'
196
257
 
197
258
  assert_file_contents_read_correctly
198
259
  end
199
260
 
200
- def test_write_file_output_format
261
+ def test_format_file
201
262
  formatter = Twine::Formatters::Tizen.new
202
263
  formatter.strings = @twine_file
203
- formatter.write_file @output_path, 'en'
204
- assert_equal content('formatter_tizen.xml'), output_content
264
+ assert_equal content('formatter_tizen.xml'), formatter.format_file('en')
205
265
  end
206
266
 
207
267
  end
@@ -211,17 +271,16 @@ class TestDjangoFormatter < FormatterTest
211
271
  super Twine::Formatters::Django
212
272
  end
213
273
 
214
- def test_read_file_format
215
- @formatter.read_file fixture('formatter_django.po'), 'en'
274
+ def test_read_format
275
+ @formatter.read content_io('formatter_django.po'), 'en'
216
276
 
217
277
  assert_file_contents_read_correctly
218
278
  end
219
279
 
220
- def test_write_file_output_format
280
+ def test_format_file
221
281
  formatter = Twine::Formatters::Django.new
222
282
  formatter.strings = @twine_file
223
- formatter.write_file @output_path, 'en'
224
- assert_equal content('formatter_django.po'), output_content
283
+ assert_equal content('formatter_django.po'), formatter.format_file('en')
225
284
  end
226
285
  end
227
286
 
@@ -230,16 +289,15 @@ class TestFlashFormatter < FormatterTest
230
289
  super Twine::Formatters::Flash
231
290
  end
232
291
 
233
- def test_read_file_format
234
- @formatter.read_file fixture('formatter_flash.properties'), 'en'
292
+ def test_read_format
293
+ @formatter.read content_io('formatter_flash.properties'), 'en'
235
294
 
236
295
  assert_file_contents_read_correctly
237
296
  end
238
297
 
239
- def test_write_file_output_format
298
+ def test_format_file
240
299
  formatter = Twine::Formatters::Flash.new
241
300
  formatter.strings = @twine_file
242
- formatter.write_file @output_path, 'en'
243
- assert_equal content('formatter_flash.properties'), output_content
301
+ assert_equal content('formatter_flash.properties'), formatter.format_file('en')
244
302
  end
245
303
  end
@@ -1,48 +1,74 @@
1
1
  require 'command_test_case'
2
2
 
3
3
  class TestGenerateAllStringFiles < CommandTestCase
4
- class TestCreateFolders < CommandTestCase
5
- def new_runner(create_folders)
6
- options = {}
7
- options[:output_path] = @output_dir
8
- options[:format] = 'apple'
9
- options[:create_folders] = create_folders
4
+ def new_runner(create_folders, twine_file = nil)
5
+ options = {}
6
+ options[:output_path] = @output_dir
7
+ options[:format] = 'apple'
8
+ options[:create_folders] = create_folders
10
9
 
10
+ unless twine_file
11
11
  twine_file = build_twine_file 'en', 'es' do
12
12
  add_section 'Section' do
13
13
  add_row key: 'value'
14
14
  end
15
15
  end
16
+ end
16
17
 
17
- Twine::Runner.new(options, twine_file)
18
+ Twine::Runner.new(options, twine_file)
19
+ end
20
+
21
+ class TestDoNotCreateFolders < TestGenerateAllStringFiles
22
+ def new_runner(twine_file = nil)
23
+ super(false, twine_file)
18
24
  end
19
25
 
20
26
  def test_fails_if_output_folder_does_not_exist
21
27
  assert_raises Twine::Error do
22
- new_runner(false).generate_all_string_files
28
+ new_runner.generate_all_string_files
23
29
  end
24
30
  end
25
31
 
26
- def test_creates_output_folder
27
- FileUtils.remove_entry_secure @output_dir
28
- new_runner(true).generate_all_string_files
29
- assert File.exists? @output_dir
32
+ def test_does_not_create_language_folders
33
+ Dir.mkdir File.join @output_dir, 'en.lproj'
34
+ new_runner.generate_all_string_files
35
+ refute File.exists?(File.join(@output_dir, 'es.lproj')), "language folder should not be created"
30
36
  end
31
37
 
32
- def test_does_not_create_language_folders_by_default
38
+ def test_prints_empty_file_warnings
33
39
  Dir.mkdir File.join @output_dir, 'en.lproj'
34
- new_runner(false).generate_all_string_files
35
- refute File.exists?(File.join(@output_dir, 'es.lproj')), "language folder should not be created"
40
+ empty_twine_file = build_twine_file('en') {}
41
+ new_runner(empty_twine_file).generate_all_string_files
42
+ assert_match "Skipping file at path", Twine::stderr.string
43
+ end
44
+ end
45
+
46
+ class TestCreateFolders < TestGenerateAllStringFiles
47
+ def new_runner(twine_file = nil)
48
+ super(true, twine_file)
49
+ end
50
+
51
+ def test_creates_output_folder
52
+ FileUtils.remove_entry_secure @output_dir
53
+ new_runner.generate_all_string_files
54
+ assert File.exists? @output_dir
36
55
  end
37
56
 
38
57
  def test_creates_language_folders
39
- new_runner(true).generate_all_string_files
58
+ new_runner.generate_all_string_files
40
59
  assert File.exists?(File.join(@output_dir, 'en.lproj')), "language folder 'en.lproj' should be created"
41
60
  assert File.exists?(File.join(@output_dir, 'es.lproj')), "language folder 'es.lproj' should be created"
42
61
  end
62
+
63
+ def test_prints_empty_file_warnings
64
+ empty_twine_file = build_twine_file('en') {}
65
+ new_runner(empty_twine_file).generate_all_string_files
66
+
67
+ assert_match "Skipping file at path", Twine::stderr.string
68
+ end
43
69
  end
44
70
 
45
- class TestDeliberate < CommandTestCase
71
+ class TestValidate < CommandTestCase
46
72
  def new_runner(validate)
47
73
  Dir.mkdir File.join @output_dir, 'values-en'
48
74