twine 0.9.1 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +56 -69
- data/lib/twine.rb +11 -3
- data/lib/twine/cli.rb +375 -155
- data/lib/twine/formatters.rb +0 -5
- data/lib/twine/formatters/abstract.rb +43 -43
- data/lib/twine/formatters/android.rb +58 -59
- data/lib/twine/formatters/apple.rb +3 -3
- data/lib/twine/formatters/django.rb +15 -21
- data/lib/twine/formatters/flash.rb +17 -20
- data/lib/twine/formatters/gettext.rb +11 -15
- data/lib/twine/formatters/jquery.rb +8 -11
- data/lib/twine/formatters/tizen.rb +4 -4
- data/lib/twine/output_processor.rb +15 -15
- data/lib/twine/placeholders.rb +26 -6
- data/lib/twine/runner.rb +95 -95
- data/lib/twine/{stringsfile.rb → twine_file.rb} +53 -48
- data/lib/twine/version.rb +1 -1
- data/test/{command_test_case.rb → command_test.rb} +5 -5
- data/test/fixtures/{consume_loc_drop.zip → consume_localization_archive.zip} +0 -0
- data/test/fixtures/formatter_django.po +3 -1
- data/test/test_abstract_formatter.rb +40 -40
- data/test/test_cli.rb +313 -211
- data/test/test_consume_localization_archive.rb +27 -0
- data/test/{test_consume_string_file.rb → test_consume_localization_file.rb} +19 -19
- data/test/test_formatters.rb +108 -43
- data/test/{test_generate_all_string_files.rb → test_generate_all_localization_files.rb} +18 -18
- data/test/{test_generate_loc_drop.rb → test_generate_localization_archive.rb} +14 -14
- data/test/{test_generate_string_file.rb → test_generate_localization_file.rb} +18 -18
- data/test/test_output_processor.rb +26 -26
- data/test/test_placeholders.rb +44 -9
- data/test/test_twine_definition.rb +111 -0
- data/test/test_twine_file.rb +58 -0
- data/test/test_validate_twine_file.rb +61 -0
- data/test/twine_file_dsl.rb +12 -12
- data/test/{twine_test_case.rb → twine_test.rb} +1 -1
- metadata +23 -23
- data/test/test_consume_loc_drop.rb +0 -27
- data/test/test_strings_file.rb +0 -58
- data/test/test_strings_row.rb +0 -47
- data/test/test_validate_strings_file.rb +0 -61
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'command_test'
|
2
2
|
|
3
|
-
class
|
3
|
+
class TestGenerateAllLocalizationFiles < CommandTest
|
4
4
|
def new_runner(create_folders, twine_file = nil)
|
5
5
|
options = {}
|
6
6
|
options[:output_path] = @output_dir
|
@@ -10,7 +10,7 @@ class TestGenerateAllStringFiles < CommandTestCase
|
|
10
10
|
unless twine_file
|
11
11
|
twine_file = build_twine_file 'en', 'es' do
|
12
12
|
add_section 'Section' do
|
13
|
-
|
13
|
+
add_definition key: 'value'
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -18,57 +18,57 @@ class TestGenerateAllStringFiles < CommandTestCase
|
|
18
18
|
Twine::Runner.new(options, twine_file)
|
19
19
|
end
|
20
20
|
|
21
|
-
class TestDoNotCreateFolders <
|
21
|
+
class TestDoNotCreateFolders < TestGenerateAllLocalizationFiles
|
22
22
|
def new_runner(twine_file = nil)
|
23
23
|
super(false, twine_file)
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_fails_if_output_folder_does_not_exist
|
27
27
|
assert_raises Twine::Error do
|
28
|
-
new_runner.
|
28
|
+
new_runner.generate_all_localization_files
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_does_not_create_language_folders
|
33
33
|
Dir.mkdir File.join @output_dir, 'en.lproj'
|
34
|
-
new_runner.
|
34
|
+
new_runner.generate_all_localization_files
|
35
35
|
refute File.exists?(File.join(@output_dir, 'es.lproj')), "language folder should not be created"
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_prints_empty_file_warnings
|
39
39
|
Dir.mkdir File.join @output_dir, 'en.lproj'
|
40
40
|
empty_twine_file = build_twine_file('en') {}
|
41
|
-
new_runner(empty_twine_file).
|
41
|
+
new_runner(empty_twine_file).generate_all_localization_files
|
42
42
|
assert_match "Skipping file at path", Twine::stderr.string
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
class TestCreateFolders <
|
46
|
+
class TestCreateFolders < TestGenerateAllLocalizationFiles
|
47
47
|
def new_runner(twine_file = nil)
|
48
48
|
super(true, twine_file)
|
49
49
|
end
|
50
50
|
|
51
51
|
def test_creates_output_folder
|
52
52
|
FileUtils.remove_entry_secure @output_dir
|
53
|
-
new_runner.
|
53
|
+
new_runner.generate_all_localization_files
|
54
54
|
assert File.exists? @output_dir
|
55
55
|
end
|
56
56
|
|
57
57
|
def test_creates_language_folders
|
58
|
-
new_runner.
|
58
|
+
new_runner.generate_all_localization_files
|
59
59
|
assert File.exists?(File.join(@output_dir, 'en.lproj')), "language folder 'en.lproj' should be created"
|
60
60
|
assert File.exists?(File.join(@output_dir, 'es.lproj')), "language folder 'es.lproj' should be created"
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_prints_empty_file_warnings
|
64
64
|
empty_twine_file = build_twine_file('en') {}
|
65
|
-
new_runner(empty_twine_file).
|
65
|
+
new_runner(empty_twine_file).generate_all_localization_files
|
66
66
|
|
67
67
|
assert_match "Skipping file at path", Twine::stderr.string
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
class TestValidate <
|
71
|
+
class TestValidate < CommandTest
|
72
72
|
def new_runner(validate)
|
73
73
|
Dir.mkdir File.join @output_dir, 'values-en'
|
74
74
|
|
@@ -79,23 +79,23 @@ class TestGenerateAllStringFiles < CommandTestCase
|
|
79
79
|
|
80
80
|
twine_file = build_twine_file 'en' do
|
81
81
|
add_section 'Section' do
|
82
|
-
|
83
|
-
|
82
|
+
add_definition key: 'value'
|
83
|
+
add_definition key: 'value'
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
87
|
Twine::Runner.new(options, twine_file)
|
88
88
|
end
|
89
89
|
|
90
|
-
def
|
90
|
+
def test_does_not_validate_twine_file
|
91
91
|
prepare_mock_formatter Twine::Formatters::Android
|
92
92
|
|
93
|
-
new_runner(false).
|
93
|
+
new_runner(false).generate_all_localization_files
|
94
94
|
end
|
95
95
|
|
96
|
-
def
|
96
|
+
def test_validates_twine_file_if_validate
|
97
97
|
assert_raises Twine::Error do
|
98
|
-
new_runner(true).
|
98
|
+
new_runner(true).generate_all_localization_files
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'command_test'
|
2
2
|
|
3
|
-
class
|
3
|
+
class TestGenerateLocalizationArchive < CommandTest
|
4
4
|
def new_runner(twine_file = nil)
|
5
5
|
options = {}
|
6
6
|
options[:output_path] = @output_path
|
@@ -9,7 +9,7 @@ class TestGenerateLocDrop < CommandTestCase
|
|
9
9
|
unless twine_file
|
10
10
|
twine_file = build_twine_file 'en', 'fr' do
|
11
11
|
add_section 'Section' do
|
12
|
-
|
12
|
+
add_definition key: 'value'
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -18,13 +18,13 @@ class TestGenerateLocDrop < CommandTestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_generates_zip_file
|
21
|
-
new_runner.
|
21
|
+
new_runner.generate_localization_archive
|
22
22
|
|
23
23
|
assert File.exists?(@output_path), "zip file should exist"
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_zip_file_structure
|
27
|
-
new_runner.
|
27
|
+
new_runner.generate_localization_archive
|
28
28
|
|
29
29
|
names = []
|
30
30
|
Zip::File.open(@output_path) do |zipfile|
|
@@ -39,16 +39,16 @@ class TestGenerateLocDrop < CommandTestCase
|
|
39
39
|
formatter = prepare_mock_formatter Twine::Formatters::Apple
|
40
40
|
formatter.expects(:format_file).twice
|
41
41
|
|
42
|
-
new_runner.
|
42
|
+
new_runner.generate_localization_archive
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_prints_empty_file_warnings
|
46
46
|
empty_twine_file = build_twine_file('en') {}
|
47
|
-
new_runner(empty_twine_file).
|
47
|
+
new_runner(empty_twine_file).generate_localization_archive
|
48
48
|
assert_match "Skipping file", Twine::stderr.string
|
49
49
|
end
|
50
50
|
|
51
|
-
class TestValidate <
|
51
|
+
class TestValidate < CommandTest
|
52
52
|
def new_runner(validate)
|
53
53
|
options = {}
|
54
54
|
options[:output_path] = @output_path
|
@@ -57,23 +57,23 @@ class TestGenerateLocDrop < CommandTestCase
|
|
57
57
|
|
58
58
|
twine_file = build_twine_file 'en' do
|
59
59
|
add_section 'Section' do
|
60
|
-
|
61
|
-
|
60
|
+
add_definition key: 'value'
|
61
|
+
add_definition key: 'value'
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
Twine::Runner.new(options, twine_file)
|
66
66
|
end
|
67
67
|
|
68
|
-
def
|
68
|
+
def test_does_not_validate_twine_file
|
69
69
|
prepare_mock_formatter Twine::Formatters::Android
|
70
70
|
|
71
|
-
new_runner(false).
|
71
|
+
new_runner(false).generate_localization_archive
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
74
|
+
def test_validates_twine_file_if_validate
|
75
75
|
assert_raises Twine::Error do
|
76
|
-
new_runner(true).
|
76
|
+
new_runner(true).generate_localization_archive
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
require '
|
1
|
+
require 'command_test'
|
2
2
|
|
3
|
-
class
|
3
|
+
class TestGenerateLocalizationFile < CommandTest
|
4
4
|
def new_runner(language, file)
|
5
5
|
options = {}
|
6
6
|
options[:output_path] = File.join(@output_dir, file) if file
|
7
7
|
options[:languages] = language if language
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
twine_file = Twine::TwineFile.new
|
10
|
+
twine_file.language_codes.concat KNOWN_LANGUAGES
|
11
11
|
|
12
|
-
Twine::Runner.new(options,
|
12
|
+
Twine::Runner.new(options, twine_file)
|
13
13
|
end
|
14
14
|
|
15
15
|
def prepare_mock_format_file_formatter(formatter_class)
|
@@ -20,25 +20,25 @@ class TestGenerateStringFile < CommandTestCase
|
|
20
20
|
def test_deducts_android_format_from_output_path
|
21
21
|
prepare_mock_format_file_formatter Twine::Formatters::Android
|
22
22
|
|
23
|
-
new_runner('fr', 'fr.xml').
|
23
|
+
new_runner('fr', 'fr.xml').generate_localization_file
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_deducts_apple_format_from_output_path
|
27
27
|
prepare_mock_format_file_formatter Twine::Formatters::Apple
|
28
28
|
|
29
|
-
new_runner('fr', 'fr.strings').
|
29
|
+
new_runner('fr', 'fr.strings').generate_localization_file
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_deducts_jquery_format_from_output_path
|
33
33
|
prepare_mock_format_file_formatter Twine::Formatters::JQuery
|
34
34
|
|
35
|
-
new_runner('fr', 'fr.json').
|
35
|
+
new_runner('fr', 'fr.json').generate_localization_file
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_deducts_gettext_format_from_output_path
|
39
39
|
prepare_mock_format_file_formatter Twine::Formatters::Gettext
|
40
40
|
|
41
|
-
new_runner('fr', 'fr.po').
|
41
|
+
new_runner('fr', 'fr.po').generate_localization_file
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_deducts_language_from_output_path
|
@@ -46,7 +46,7 @@ class TestGenerateStringFile < CommandTestCase
|
|
46
46
|
formatter = prepare_mock_formatter Twine::Formatters::Android
|
47
47
|
formatter.expects(:format_file).with(random_language).returns(true)
|
48
48
|
|
49
|
-
new_runner(nil, "#{random_language}.xml").
|
49
|
+
new_runner(nil, "#{random_language}.xml").generate_localization_file
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_returns_error_if_nothing_written
|
@@ -54,11 +54,11 @@ class TestGenerateStringFile < CommandTestCase
|
|
54
54
|
formatter.expects(:format_file).returns(false)
|
55
55
|
|
56
56
|
assert_raises Twine::Error do
|
57
|
-
new_runner('fr', 'fr.xml').
|
57
|
+
new_runner('fr', 'fr.xml').generate_localization_file
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
class TestValidate <
|
61
|
+
class TestValidate < CommandTest
|
62
62
|
def new_runner(validate)
|
63
63
|
options = {}
|
64
64
|
options[:output_path] = @output_path
|
@@ -68,23 +68,23 @@ class TestGenerateStringFile < CommandTestCase
|
|
68
68
|
|
69
69
|
twine_file = build_twine_file 'en' do
|
70
70
|
add_section 'Section' do
|
71
|
-
|
72
|
-
|
71
|
+
add_definition key: 'value'
|
72
|
+
add_definition key: 'value'
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
76
|
Twine::Runner.new(options, twine_file)
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def test_does_not_validate_twine_file
|
80
80
|
prepare_mock_formatter Twine::Formatters::Android
|
81
81
|
|
82
|
-
new_runner(false).
|
82
|
+
new_runner(false).generate_localization_file
|
83
83
|
end
|
84
84
|
|
85
|
-
def
|
85
|
+
def test_validates_twine_file_if_validate
|
86
86
|
assert_raises Twine::Error do
|
87
|
-
new_runner(true).
|
87
|
+
new_runner(true).generate_localization_file
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -1,84 +1,84 @@
|
|
1
|
-
require '
|
1
|
+
require 'twine_test'
|
2
2
|
|
3
|
-
class TestOutputProcessor <
|
3
|
+
class TestOutputProcessor < TwineTest
|
4
4
|
def setup
|
5
5
|
super
|
6
6
|
|
7
|
-
@
|
7
|
+
@twine_file = build_twine_file 'en', 'fr' do
|
8
8
|
add_section 'Section' do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
add_definition key1: 'value1', tags: ['tag1']
|
10
|
+
add_definition key2: 'value2', tags: ['tag1', 'tag2']
|
11
|
+
add_definition key3: 'value3', tags: ['tag2']
|
12
|
+
add_definition key4: { en: 'value4-en', fr: 'value4-fr' }
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_includes_all_keys_by_default
|
18
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
18
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, {})
|
19
19
|
result = processor.process('en')
|
20
20
|
|
21
|
-
assert_equal %w(key1 key2 key3 key4), result.
|
21
|
+
assert_equal %w(key1 key2 key3 key4), result.definitions_by_key.keys.sort
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_filter_by_tag
|
25
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
25
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { tags: [['tag1']] })
|
26
26
|
result = processor.process('en')
|
27
27
|
|
28
|
-
assert_equal %w(key1 key2), result.
|
28
|
+
assert_equal %w(key1 key2), result.definitions_by_key.keys.sort
|
29
29
|
end
|
30
30
|
|
31
31
|
def test_filter_by_multiple_tags
|
32
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
32
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { tags: [['tag1', 'tag2']] })
|
33
33
|
result = processor.process('en')
|
34
34
|
|
35
|
-
assert_equal %w(key1 key2 key3), result.
|
35
|
+
assert_equal %w(key1 key2 key3), result.definitions_by_key.keys.sort
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_filter_untagged
|
39
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
39
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { tags: [['tag1']], untagged: true })
|
40
40
|
result = processor.process('en')
|
41
41
|
|
42
|
-
assert_equal %w(key1 key2 key4), result.
|
42
|
+
assert_equal %w(key1 key2 key4), result.definitions_by_key.keys.sort
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_include_translated
|
46
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
46
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { include: :translated })
|
47
47
|
result = processor.process('fr')
|
48
48
|
|
49
|
-
assert_equal %w(key4), result.
|
49
|
+
assert_equal %w(key4), result.definitions_by_key.keys.sort
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_include_untranslated
|
53
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
53
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { include: :untranslated })
|
54
54
|
result = processor.process('fr')
|
55
55
|
|
56
|
-
assert_equal %w(key1 key2 key3), result.
|
56
|
+
assert_equal %w(key1 key2 key3), result.definitions_by_key.keys.sort
|
57
57
|
end
|
58
58
|
|
59
|
-
class TranslationFallback <
|
59
|
+
class TranslationFallback < TwineTest
|
60
60
|
def setup
|
61
61
|
super
|
62
62
|
|
63
|
-
@
|
63
|
+
@twine_file = build_twine_file 'en', 'fr', 'de' do
|
64
64
|
add_section 'Section' do
|
65
|
-
|
65
|
+
add_definition key1: { en: 'value1-en', fr: 'value1-fr' }
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_fallback_to_default_language
|
71
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
71
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, {})
|
72
72
|
result = processor.process('de')
|
73
73
|
|
74
|
-
assert_equal 'value1-en', result.
|
74
|
+
assert_equal 'value1-en', result.definitions_by_key['key1'].translations['de']
|
75
75
|
end
|
76
76
|
|
77
77
|
def test_fallback_to_developer_language
|
78
|
-
processor = Twine::Processors::OutputProcessor.new(@
|
78
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, {developer_language: 'fr'})
|
79
79
|
result = processor.process('de')
|
80
80
|
|
81
|
-
assert_equal 'value1-fr', result.
|
81
|
+
assert_equal 'value1-fr', result.definitions_by_key['key1'].translations['de']
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
data/test/test_placeholders.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'twine_test'
|
2
2
|
|
3
|
-
class
|
3
|
+
class PlaceholderTest < TwineTest
|
4
4
|
def assert_starts_with(prefix, value)
|
5
5
|
msg = message(nil) { "Expected #{mu_pp(value)} to start with #{mu_pp(prefix)}" }
|
6
6
|
assert value.start_with?(prefix), msg
|
@@ -11,23 +11,25 @@ class PlaceholderTestCase < TwineTestCase
|
|
11
11
|
lucky = lambda { rand > 0.5 }
|
12
12
|
placeholder = '%'
|
13
13
|
placeholder += (rand * 20).to_i.to_s + '$' if lucky.call
|
14
|
-
placeholder += '-+
|
14
|
+
placeholder += '-+0#'.chars.to_a.sample if lucky.call
|
15
15
|
placeholder += (0.upto(20).map(&:to_s) << "*").sample if lucky.call
|
16
16
|
placeholder += '.' + (0.upto(20).map(&:to_s) << "*").sample if lucky.call
|
17
17
|
placeholder += %w(h hh l ll L z j t).sample if lucky.call
|
18
18
|
placeholder += type || 'diufFeEgGxXocpaA'.chars.to_a.sample # this does not contain s or @ because strings are a special case
|
19
19
|
end
|
20
|
-
end
|
21
20
|
|
22
|
-
class
|
23
|
-
class ToAndroid < PlaceholderTestCase
|
21
|
+
class ToAndroid < PlaceholderTest
|
24
22
|
def to_android(value)
|
25
23
|
Twine::Placeholders.convert_placeholders_from_twine_to_android(value)
|
26
24
|
end
|
27
25
|
|
28
|
-
def
|
26
|
+
def test_replaces_simple_string_placeholder
|
27
|
+
assert_equal "some '%s' value", to_android("some '%@' value")
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_replaces_complicated_string_placeholder
|
29
31
|
placeholder = placeholder('@')
|
30
|
-
expected = placeholder
|
32
|
+
expected = placeholder.dup
|
31
33
|
expected[-1] = 's'
|
32
34
|
assert_equal "some #{expected} value", to_android("some #{placeholder} value")
|
33
35
|
end
|
@@ -41,6 +43,11 @@ class PlaceholderTest < TwineTestCase
|
|
41
43
|
assert_equal "some % value", to_android("some % value")
|
42
44
|
end
|
43
45
|
|
46
|
+
def test_does_not_modify_single_percent_signs_when_followed_by_space_and_format_letter
|
47
|
+
# Said differently: formartter parser should not recognize %a in "70% and"
|
48
|
+
assert_equal 'If 70% and 30% dog 80% end', to_android('If 70% and 30% dog 80% end')
|
49
|
+
end
|
50
|
+
|
44
51
|
def test_escapes_single_percent_signs_if_placeholder_present
|
45
52
|
assert_starts_with "some %% v", to_android("some % value #{placeholder}")
|
46
53
|
end
|
@@ -74,7 +81,7 @@ class PlaceholderTest < TwineTestCase
|
|
74
81
|
end
|
75
82
|
end
|
76
83
|
|
77
|
-
class FromAndroid <
|
84
|
+
class FromAndroid < PlaceholderTest
|
78
85
|
def from_android(value)
|
79
86
|
Twine::Placeholders.convert_placeholders_from_android_to_twine(value)
|
80
87
|
end
|
@@ -83,4 +90,32 @@ class PlaceholderTest < TwineTestCase
|
|
83
90
|
assert_equal "some %@ value", from_android("some %s value")
|
84
91
|
end
|
85
92
|
end
|
93
|
+
|
94
|
+
class ToFlash < PlaceholderTest
|
95
|
+
def to_flash(value)
|
96
|
+
Twine::Placeholders.convert_placeholders_from_twine_to_flash(value)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_replaces_placeholder
|
100
|
+
assert_equal "some {0} text", to_flash("some #{placeholder} text")
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_replaces_string_placeholder
|
104
|
+
assert_equal "some {0} text", to_flash("some #{placeholder('@')} text")
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_numbers_placeholders
|
108
|
+
assert_equal "some {0} more {1} text {2}", to_flash("some #{placeholder('@')} more #{placeholder('@')} text #{placeholder('@')}")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class FromFlash < PlaceholderTest
|
113
|
+
def from_flash(value)
|
114
|
+
Twine::Placeholders.convert_placeholders_from_flash_to_twine(value)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_maps_all_placeholders_to_string
|
118
|
+
assert_equal "some %@ more %@ text %@", from_flash("some {0} more {1} text {2}")
|
119
|
+
end
|
120
|
+
end
|
86
121
|
end
|