twine 0.7.0 → 0.8.0

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -0
  3. data/lib/twine.rb +21 -0
  4. data/lib/twine/cli.rb +68 -91
  5. data/lib/twine/formatters/abstract.rb +133 -82
  6. data/lib/twine/formatters/android.rb +49 -67
  7. data/lib/twine/formatters/apple.rb +33 -47
  8. data/lib/twine/formatters/django.rb +38 -48
  9. data/lib/twine/formatters/flash.rb +25 -40
  10. data/lib/twine/formatters/gettext.rb +37 -44
  11. data/lib/twine/formatters/jquery.rb +31 -33
  12. data/lib/twine/formatters/tizen.rb +38 -55
  13. data/lib/twine/output_processor.rb +57 -0
  14. data/lib/twine/placeholders.rb +54 -0
  15. data/lib/twine/runner.rb +78 -115
  16. data/lib/twine/stringsfile.rb +83 -60
  17. data/lib/twine/version.rb +1 -1
  18. data/test/command_test_case.rb +12 -0
  19. data/test/fixtures/consume_loc_drop.zip +0 -0
  20. data/test/fixtures/formatter_android.xml +15 -0
  21. data/test/fixtures/formatter_apple.strings +20 -0
  22. data/test/fixtures/formatter_django.po +28 -0
  23. data/test/fixtures/formatter_flash.properties +15 -0
  24. data/test/fixtures/formatter_gettext.po +26 -0
  25. data/test/fixtures/formatter_jquery.json +7 -0
  26. data/test/fixtures/formatter_tizen.xml +15 -0
  27. data/test/fixtures/gettext_multiline.po +10 -0
  28. data/test/fixtures/twine_accent_values.txt +13 -0
  29. data/test/test_abstract_formatter.rb +152 -0
  30. data/test/test_cli.rb +288 -0
  31. data/test/test_consume_loc_drop.rb +27 -0
  32. data/test/test_consume_string_file.rb +53 -0
  33. data/test/test_formatters.rb +236 -0
  34. data/test/test_generate_all_string_files.rb +44 -0
  35. data/test/test_generate_loc_drop.rb +44 -0
  36. data/test/test_generate_string_file.rb +51 -0
  37. data/test/test_output_processor.rb +85 -0
  38. data/test/test_placeholders.rb +86 -0
  39. data/test/test_strings_file.rb +58 -0
  40. data/test/test_strings_row.rb +47 -0
  41. data/test/test_validate_strings_file.rb +55 -0
  42. data/test/twine_file_dsl.rb +46 -0
  43. data/test/twine_test_case.rb +44 -0
  44. metadata +80 -37
  45. data/test/fixtures/en-1.json +0 -5
  46. data/test/fixtures/en-1.po +0 -16
  47. data/test/fixtures/en-1.strings +0 -10
  48. data/test/fixtures/en-2.po +0 -23
  49. data/test/fixtures/en-3.xml +0 -8
  50. data/test/fixtures/fr-1.xml +0 -10
  51. data/test/fixtures/strings-1.txt +0 -17
  52. data/test/fixtures/strings-2.txt +0 -5
  53. data/test/fixtures/strings-3.txt +0 -5
  54. data/test/fixtures/test-json-line-breaks/consumed.txt +0 -5
  55. data/test/fixtures/test-json-line-breaks/generated.json +0 -3
  56. data/test/fixtures/test-json-line-breaks/line-breaks.json +0 -3
  57. data/test/fixtures/test-json-line-breaks/line-breaks.txt +0 -4
  58. data/test/fixtures/test-output-1.txt +0 -12
  59. data/test/fixtures/test-output-10.txt +0 -9
  60. data/test/fixtures/test-output-11.txt +0 -9
  61. data/test/fixtures/test-output-12.txt +0 -12
  62. data/test/fixtures/test-output-2.txt +0 -12
  63. data/test/fixtures/test-output-3.txt +0 -18
  64. data/test/fixtures/test-output-4.txt +0 -21
  65. data/test/fixtures/test-output-5.txt +0 -4
  66. data/test/fixtures/test-output-6.txt +0 -10
  67. data/test/fixtures/test-output-7.txt +0 -16
  68. data/test/fixtures/test-output-8.txt +0 -9
  69. data/test/fixtures/test-output-9.txt +0 -21
  70. data/test/twine_test.rb +0 -134
@@ -0,0 +1,288 @@
1
+ require 'twine_test_case'
2
+
3
+ class CLITestCase < TwineTestCase
4
+ def setup
5
+ super
6
+
7
+ @strings_file_path = File.join @output_dir, SecureRandom.uuid
8
+ @input_path = File.join @output_dir, SecureRandom.uuid
9
+ @input_dir = @output_dir
10
+ end
11
+
12
+ def parse(command)
13
+ @options = Twine::CLI::parse command.split
14
+ end
15
+
16
+ class TestValidateStringsFile < CLITestCase
17
+ def test_command
18
+ parse "validate-strings-file #{@strings_file_path}"
19
+
20
+ assert_equal 'validate-strings-file', @options[:command]
21
+ assert_equal @strings_file_path, @options[:strings_file]
22
+ end
23
+
24
+ def test_missing_parameter
25
+ assert_raises Twine::Error do
26
+ parse 'validate-strings-file'
27
+ end
28
+ end
29
+
30
+ def test_extra_parameter
31
+ assert_raises Twine::Error do
32
+ parse 'validate-strings-file strings extra'
33
+ end
34
+ end
35
+ end
36
+
37
+ class TestGenerateStringFile < CLITestCase
38
+ def test_command
39
+ parse "generate-string-file #{@strings_file_path} #{@output_path}"
40
+
41
+ assert_equal 'generate-string-file', @options[:command]
42
+ assert_equal @strings_file_path, @options[:strings_file]
43
+ assert_equal @output_path, @options[:output_path]
44
+ end
45
+
46
+ def test_missing_parameter
47
+ assert_raises Twine::Error do
48
+ parse 'generate-string-file strings'
49
+ end
50
+ end
51
+
52
+ def test_extra_parameter
53
+ assert_raises Twine::Error do
54
+ parse 'generate-string-file strings output extra'
55
+ end
56
+ end
57
+
58
+ def test_only_allows_one_language
59
+ assert_raises Twine::Error do
60
+ parse "generate-string-file strings output --lang en,fr"
61
+ end
62
+ end
63
+ end
64
+
65
+ class TestGenerateAllStringFiles < CLITestCase
66
+ def test_command
67
+ parse "generate-all-string-files #{@strings_file_path} #{@output_dir}"
68
+
69
+ assert_equal 'generate-all-string-files', @options[:command]
70
+ assert_equal @strings_file_path, @options[:strings_file]
71
+ assert_equal @output_dir, @options[:output_path]
72
+ end
73
+
74
+ def test_missing_parameter
75
+ assert_raises Twine::Error do
76
+ parse "generate-all-string-files strings"
77
+ end
78
+ end
79
+
80
+ def test_extra_parameter
81
+ assert_raises Twine::Error do
82
+ parse "generate-all-string-files strings output extra"
83
+ end
84
+ end
85
+ end
86
+
87
+ class TestConsumeStringFile < CLITestCase
88
+ def test_command
89
+ parse "consume-string-file #{@strings_file_path} #{@input_path}"
90
+
91
+ assert_equal 'consume-string-file', @options[:command]
92
+ assert_equal @strings_file_path, @options[:strings_file]
93
+ assert_equal @input_path, @options[:input_path]
94
+ end
95
+
96
+ def test_missing_parameter
97
+ assert_raises Twine::Error do
98
+ parse "consume-string-file strings"
99
+ end
100
+ end
101
+
102
+ def test_extra_parameter
103
+ assert_raises Twine::Error do
104
+ parse "consume-string-file strings output extra"
105
+ end
106
+ end
107
+
108
+ def test_only_allows_one_language
109
+ assert_raises Twine::Error do
110
+ parse "consume-string-file strings output --lang en,fr"
111
+ end
112
+ end
113
+ end
114
+
115
+ class TestConsumeAllStringFiles < CLITestCase
116
+ def test_command
117
+ parse "consume-all-string-files #{@strings_file_path} #{@input_dir}"
118
+
119
+ assert_equal 'consume-all-string-files', @options[:command]
120
+ assert_equal @strings_file_path, @options[:strings_file]
121
+ assert_equal @input_dir, @options[:input_path]
122
+ end
123
+
124
+ def test_missing_parameter
125
+ assert_raises Twine::Error do
126
+ parse "consume-all-string-files strings"
127
+ end
128
+ end
129
+
130
+ def test_extra_parameter
131
+ assert_raises Twine::Error do
132
+ parse "consume-all-string-files strings output extra"
133
+ end
134
+ end
135
+ end
136
+
137
+ class TestGenerateLocDrop < CLITestCase
138
+ def test_command
139
+ parse "generate-loc-drop #{@strings_file_path} #{@output_path} --format apple"
140
+
141
+ assert_equal 'generate-loc-drop', @options[:command]
142
+ assert_equal @strings_file_path, @options[:strings_file]
143
+ assert_equal @output_path, @options[:output_path]
144
+ end
145
+
146
+ def test_missing_parameter
147
+ assert_raises Twine::Error do
148
+ parse "generate-loc-drop strings --format apple"
149
+ end
150
+ end
151
+
152
+ def test_extra_parameter
153
+ assert_raises Twine::Error do
154
+ parse "generate-loc-drop strings output extra --format apple"
155
+ end
156
+ end
157
+
158
+ def test_format_needed
159
+ assert_raises Twine::Error do
160
+ parse "generate-loc-drop strings output"
161
+ end
162
+ end
163
+ end
164
+
165
+ class TestConsumeLocDrop < CLITestCase
166
+ def test_command
167
+ parse "consume-loc-drop #{@strings_file_path} #{@input_path}"
168
+
169
+ assert_equal 'consume-loc-drop', @options[:command]
170
+ assert_equal @strings_file_path, @options[:strings_file]
171
+ assert_equal @input_path, @options[:input_path]
172
+ end
173
+
174
+ def test_missing_parameter
175
+ assert_raises Twine::Error do
176
+ parse "consume-loc-drop strings"
177
+ end
178
+ end
179
+
180
+ def test_extra_parameter
181
+ assert_raises Twine::Error do
182
+ parse "consume-loc-drop strings input extra"
183
+ end
184
+ end
185
+ end
186
+
187
+ class TestParameters < CLITestCase
188
+ def parse_with(parameter)
189
+ parse 'validate-strings-file input.txt ' + parameter
190
+ end
191
+
192
+ def test_default_options
193
+ parse_with ''
194
+ expected = {command: 'validate-strings-file', strings_file: 'input.txt', include: "all"}
195
+ assert_equal expected, @options
196
+ end
197
+
198
+ def test_create_folders
199
+ parse_with '--create-folders'
200
+ assert @options[:create_folders]
201
+ end
202
+
203
+ def test_consume_all
204
+ parse_with '--consume-all'
205
+ assert @options[:consume_all]
206
+ end
207
+
208
+ def test_consume_comments
209
+ parse_with '--consume-comments'
210
+ assert @options[:consume_comments]
211
+ end
212
+
213
+ def test_untagged
214
+ parse_with '--untagged'
215
+ assert @options[:untagged]
216
+ end
217
+
218
+ def test_developer_language
219
+ random_language = KNOWN_LANGUAGES.sample
220
+ parse_with "--developer-lang #{random_language}"
221
+ assert_equal random_language, @options[:developer_language]
222
+ end
223
+
224
+ def test_single_language
225
+ random_language = KNOWN_LANGUAGES.sample
226
+ parse_with "--lang #{random_language}"
227
+ assert_equal [random_language], @options[:languages]
228
+ end
229
+
230
+ def test_multiple_languages
231
+ random_languages = KNOWN_LANGUAGES.shuffle[0, 3]
232
+ parse_with "--lang #{random_languages.join(',')}"
233
+ assert_equal random_languages.sort, @options[:languages].sort
234
+ end
235
+
236
+ def test_single_tag
237
+ random_tag = "tag#{rand(100)}"
238
+ parse_with "--tags #{random_tag}"
239
+ assert_equal [random_tag], @options[:tags]
240
+ end
241
+
242
+ def test_multiple_tags
243
+ random_tags = ([nil] * 3).map { "tag#{rand(100)}" }
244
+ parse_with "--tags #{random_tags.join(',')}"
245
+ assert_equal random_tags.sort, @options[:tags].sort
246
+ end
247
+
248
+ def test_format
249
+ random_format = Twine::Formatters.formatters.sample::FORMAT_NAME
250
+ parse_with "--format #{random_format}"
251
+ assert_equal random_format, @options[:format]
252
+ end
253
+
254
+ def test_format_ignores_case
255
+ random_format = Twine::Formatters.formatters.sample::FORMAT_NAME
256
+ parse_with "--format #{random_format.upcase}"
257
+ assert_equal random_format, @options[:format]
258
+ end
259
+
260
+ def test_include
261
+ random_set = ['all', 'translated', 'untranslated'].sample
262
+ parse_with "--include #{random_set}"
263
+ assert_equal random_set, @options[:include]
264
+ end
265
+
266
+ def test_include_ignores_case
267
+ random_set = ['all', 'translated', 'untranslated'].sample
268
+ parse_with "--include #{random_set.upcase}"
269
+ assert_equal random_set, @options[:include]
270
+ end
271
+
272
+ def test_output_path
273
+ parse_with "--output-file #{@output_path}"
274
+ assert_equal @output_path, @options[:output_path]
275
+ end
276
+
277
+ def test_file_name
278
+ random_filename = "#{rand(10000)}"
279
+ parse_with "--file-name #{random_filename}"
280
+ assert_equal random_filename, @options[:file_name]
281
+ end
282
+
283
+ def test_encoding
284
+ parse_with '--encoding UTF16'
285
+ assert_equal 'UTF16', @options[:output_encoding]
286
+ end
287
+ end
288
+ end
@@ -0,0 +1,27 @@
1
+ require 'command_test_case'
2
+
3
+ class TestConsumeLocDrop < CommandTestCase
4
+ def setup
5
+ super
6
+
7
+ options = {}
8
+ options[:input_path] = fixture 'consume_loc_drop.zip'
9
+ options[:output_path] = @output_path
10
+ options[:format] = 'apple'
11
+
12
+ @twine_file = build_twine_file 'en', 'es' do
13
+ add_section 'Section' do
14
+ add_row key1: 'value1'
15
+ end
16
+ end
17
+
18
+ @runner = Twine::Runner.new(options, @twine_file)
19
+ end
20
+
21
+ def test_consumes_zip_file
22
+ @runner.consume_loc_drop
23
+
24
+ assert @twine_file.strings_map['key1'].translations['en'], 'value1-english'
25
+ assert @twine_file.strings_map['key1'].translations['es'], 'value1-spanish'
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ require 'command_test_case'
2
+
3
+ class TestConsumeStringFile < CommandTestCase
4
+ def new_runner(language, file)
5
+ options = {}
6
+ options[:output_path] = File.join(@output_dir, file) if file
7
+ options[:input_path] = File.join(@output_dir, file) if file
8
+ FileUtils.touch options[:input_path]
9
+ options[:languages] = language if language
10
+
11
+ @strings = Twine::StringsFile.new
12
+ @strings.language_codes.concat KNOWN_LANGUAGES
13
+
14
+ Twine::Runner.new(options, @strings)
15
+ end
16
+
17
+ def prepare_mock_read_file_formatter(formatter_class)
18
+ formatter = prepare_mock_formatter(formatter_class)
19
+ formatter.expects(:read_file)
20
+ end
21
+
22
+ def test_deducts_android_format_from_output_path
23
+ prepare_mock_read_file_formatter Twine::Formatters::Android
24
+
25
+ new_runner('fr', 'fr.xml').consume_string_file
26
+ end
27
+
28
+ def test_deducts_apple_format_from_output_path
29
+ prepare_mock_read_file_formatter Twine::Formatters::Apple
30
+
31
+ new_runner('fr', 'fr.strings').consume_string_file
32
+ end
33
+
34
+ def test_deducts_jquery_format_from_output_path
35
+ prepare_mock_read_file_formatter Twine::Formatters::JQuery
36
+
37
+ new_runner('fr', 'fr.json').consume_string_file
38
+ end
39
+
40
+ def test_deducts_gettext_format_from_output_path
41
+ prepare_mock_read_file_formatter Twine::Formatters::Gettext
42
+
43
+ new_runner('fr', 'fr.po').consume_string_file
44
+ end
45
+
46
+ def test_deducts_language_from_input_path
47
+ random_language = KNOWN_LANGUAGES.sample
48
+ formatter = prepare_mock_formatter Twine::Formatters::Android
49
+ formatter.expects(:read_file).with(anything, random_language)
50
+
51
+ new_runner(nil, "#{random_language}.xml").consume_string_file
52
+ end
53
+ end
@@ -0,0 +1,236 @@
1
+ require 'twine_test_case'
2
+
3
+ class FormatterTest < TwineTestCase
4
+ def setup(formatter_class)
5
+ super()
6
+
7
+ @twine_file = build_twine_file 'en' do
8
+ add_section 'Section 1' do
9
+ add_row key1: 'value1-english', comment: 'comment key1'
10
+ add_row key2: 'value2-english'
11
+ end
12
+
13
+ add_section 'Section 2' do
14
+ add_row key3: 'value3-english'
15
+ add_row key4: 'value4-english', comment: 'comment key4'
16
+ end
17
+ end
18
+
19
+ @strings = Twine::StringsFile.new
20
+ @formatter = formatter_class.new @strings, { consume_all: true, consume_comments: true }
21
+ end
22
+
23
+ def assert_translations_read_correctly
24
+ 1.upto(4) do |i|
25
+ assert_equal "value#{i}-english", @strings.strings_map["key#{i}"].translations['en']
26
+ end
27
+ end
28
+
29
+ def assert_file_contents_read_correctly
30
+ assert_translations_read_correctly
31
+
32
+ assert_equal "comment key1", @strings.strings_map["key1"].comment
33
+ assert_equal "comment key4", @strings.strings_map["key4"].comment
34
+ end
35
+ end
36
+
37
+ class TestAndroidFormatter < FormatterTest
38
+ def setup
39
+ super Twine::Formatters::Android
40
+ end
41
+
42
+ def test_read_file_format
43
+ @formatter.read_file fixture('formatter_android.xml'), 'en'
44
+
45
+ assert_file_contents_read_correctly
46
+ end
47
+
48
+ def test_set_translation_converts_leading_spaces
49
+ @formatter.set_translation_for_key 'key1', 'en', "\u0020value"
50
+ assert_equal ' value', @strings.strings_map['key1'].translations['en']
51
+ end
52
+
53
+ def test_set_translation_coverts_trailing_spaces
54
+ @formatter.set_translation_for_key 'key1', 'en', "value\u0020\u0020"
55
+ assert_equal 'value ', @strings.strings_map['key1'].translations['en']
56
+ end
57
+
58
+ def test_set_translation_converts_string_placeholders
59
+ @formatter.set_translation_for_key 'key1', 'en', "value %s"
60
+ assert_equal 'value %@', @strings.strings_map['key1'].translations['en']
61
+ end
62
+
63
+ def test_set_translation_unescapes_at_signs
64
+ @formatter.set_translation_for_key 'key1', 'en', '\@value'
65
+ assert_equal '@value', @strings.strings_map['key1'].translations['en']
66
+ end
67
+
68
+ def test_write_file_output_format
69
+ formatter = Twine::Formatters::Android.new @twine_file, {}
70
+ formatter.write_file @output_path, 'en'
71
+ assert_equal content('formatter_android.xml'), output_content
72
+ end
73
+
74
+ def test_format_key_with_space
75
+ assert_equal 'key ', @formatter.format_key('key ')
76
+ end
77
+
78
+ def test_format_value_with_leading_space
79
+ assert_equal "\\u0020value", @formatter.format_value(' value')
80
+ end
81
+
82
+ def test_format_value_with_trailing_space
83
+ assert_equal "value\\u0020", @formatter.format_value('value ')
84
+ end
85
+
86
+ def test_format_value_escapes_single_quotes
87
+ skip 'not working with ruby 2.0'
88
+ # http://stackoverflow.com/questions/18735608/cgiescapehtml-is-escaping-single-quote
89
+ assert_equal "not \\'so\\' easy", @formatter.format_value("not 'so' easy")
90
+ end
91
+
92
+ def test_format_value_escapes_non_resource_identifier_at_signs
93
+ assert_equal '\@whatever \@\@', @formatter.format_value('@whatever @@')
94
+ end
95
+
96
+ def test_format_value_does_not_modify_resource_identifiers
97
+ identifier = '@android:string/cancel'
98
+ assert_equal identifier, @formatter.format_value(identifier)
99
+ end
100
+ end
101
+
102
+ class TestAppleFormatter < FormatterTest
103
+ def setup
104
+ super Twine::Formatters::Apple
105
+ end
106
+
107
+ def test_read_file_format
108
+ @formatter.read_file fixture('formatter_apple.strings'), 'en'
109
+
110
+ assert_file_contents_read_correctly
111
+ end
112
+
113
+ def test_write_file_output_format
114
+ formatter = Twine::Formatters::Apple.new @twine_file, {}
115
+ formatter.write_file @output_path, 'en'
116
+ assert_equal content('formatter_apple.strings'), output_content
117
+ end
118
+
119
+ def test_format_key_with_space
120
+ assert_equal 'key ', @formatter.format_key('key ')
121
+ end
122
+
123
+ def test_format_value_with_leading_space
124
+ assert_equal ' value', @formatter.format_value(' value')
125
+ end
126
+
127
+ def test_format_value_with_trailing_space
128
+ assert_equal 'value ', @formatter.format_value('value ')
129
+ end
130
+ end
131
+
132
+ class TestJQueryFormatter < FormatterTest
133
+
134
+ def setup
135
+ super Twine::Formatters::JQuery
136
+ end
137
+
138
+ def test_read_file_format
139
+ @formatter.read_file fixture('formatter_jquery.json'), 'en'
140
+
141
+ assert_translations_read_correctly
142
+ end
143
+
144
+ def test_write_file_output_format
145
+ formatter = Twine::Formatters::JQuery.new @twine_file, {}
146
+ formatter.write_file @output_path, 'en'
147
+ assert_equal content('formatter_jquery.json'), output_content
148
+ end
149
+
150
+ def test_format_value_with_newline
151
+ assert_equal "value\nwith\nline\nbreaks", @formatter.format_value("value\nwith\nline\nbreaks")
152
+ end
153
+ end
154
+
155
+ class TestGettextFormatter < FormatterTest
156
+
157
+ def setup
158
+ super Twine::Formatters::Gettext
159
+ end
160
+
161
+ def test_read_file_format
162
+ @formatter.read_file fixture('formatter_gettext.po'), 'en'
163
+
164
+ assert_file_contents_read_correctly
165
+ end
166
+
167
+ def test_read_file_with_multiple_line_value
168
+ @formatter.read_file fixture('gettext_multiline.po'), 'en'
169
+
170
+ assert_equal 'multiline\nstring', @strings.strings_map['key1'].translations['en']
171
+ end
172
+
173
+ def test_write_file_output_format
174
+ formatter = Twine::Formatters::Gettext.new @twine_file, {}
175
+ formatter.write_file @output_path, 'en'
176
+ assert_equal content('formatter_gettext.po'), output_content
177
+ end
178
+
179
+ end
180
+
181
+ class TestTizenFormatter < FormatterTest
182
+
183
+ def setup
184
+ super Twine::Formatters::Tizen
185
+ end
186
+
187
+ def test_read_file_format
188
+ skip 'the current implementation of Tizen formatter does not support read_file'
189
+ @formatter.read_file fixture('formatter_tizen.xml'), 'en'
190
+
191
+ assert_file_contents_read_correctly
192
+ end
193
+
194
+ def test_write_file_output_format
195
+ formatter = Twine::Formatters::Tizen.new @twine_file, {}
196
+ formatter.write_file @output_path, 'en'
197
+ assert_equal content('formatter_tizen.xml'), output_content
198
+ end
199
+
200
+ end
201
+
202
+ class TestDjangoFormatter < FormatterTest
203
+ def setup
204
+ super Twine::Formatters::Django
205
+ end
206
+
207
+ def test_read_file_format
208
+ @formatter.read_file fixture('formatter_django.po'), 'en'
209
+
210
+ assert_file_contents_read_correctly
211
+ end
212
+
213
+ def test_write_file_output_format
214
+ formatter = Twine::Formatters::Django.new @twine_file, {}
215
+ formatter.write_file @output_path, 'en'
216
+ assert_equal content('formatter_django.po'), output_content
217
+ end
218
+ end
219
+
220
+ class TestFlashFormatter < FormatterTest
221
+ def setup
222
+ super Twine::Formatters::Flash
223
+ end
224
+
225
+ def test_read_file_format
226
+ @formatter.read_file fixture('formatter_flash.properties'), 'en'
227
+
228
+ assert_file_contents_read_correctly
229
+ end
230
+
231
+ def test_write_file_output_format
232
+ formatter = Twine::Formatters::Flash.new @twine_file, {}
233
+ formatter.write_file @output_path, 'en'
234
+ assert_equal content('formatter_flash.properties'), output_content
235
+ end
236
+ end