yury-twine 0.9.1
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.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/LICENSE +30 -0
- data/README.md +230 -0
- data/bin/twine +7 -0
- data/lib/twine.rb +36 -0
- data/lib/twine/cli.rb +200 -0
- data/lib/twine/encoding.rb +22 -0
- data/lib/twine/formatters.rb +20 -0
- data/lib/twine/formatters/abstract.rb +187 -0
- data/lib/twine/formatters/android.rb +254 -0
- data/lib/twine/formatters/apple.rb +328 -0
- data/lib/twine/output_processor.rb +57 -0
- data/lib/twine/placeholders.rb +54 -0
- data/lib/twine/plugin.rb +62 -0
- data/lib/twine/runner.rb +332 -0
- data/lib/twine/twine_file.rb +266 -0
- data/lib/twine/version.rb +3 -0
- data/test/command_test.rb +14 -0
- data/test/fixtures/consume_loc_drop.zip +0 -0
- data/test/fixtures/enc_utf16be.dummy +0 -0
- data/test/fixtures/enc_utf16be_bom.dummy +0 -0
- data/test/fixtures/enc_utf16le.dummy +0 -0
- data/test/fixtures/enc_utf16le_bom.dummy +0 -0
- data/test/fixtures/enc_utf8.dummy +2 -0
- data/test/fixtures/formatter_android.xml +15 -0
- data/test/fixtures/formatter_apple.strings +20 -0
- data/test/fixtures/formatter_django.po +30 -0
- data/test/fixtures/formatter_flash.properties +15 -0
- data/test/fixtures/formatter_gettext.po +26 -0
- data/test/fixtures/formatter_jquery.json +7 -0
- data/test/fixtures/formatter_tizen.xml +15 -0
- data/test/fixtures/gettext_multiline.po +10 -0
- data/test/fixtures/twine_accent_values.txt +13 -0
- data/test/test_abstract_formatter.rb +165 -0
- data/test/test_cli.rb +304 -0
- data/test/test_consume_loc_drop.rb +27 -0
- data/test/test_consume_localization_file.rb +119 -0
- data/test/test_formatters.rb +363 -0
- data/test/test_generate_all_localization_files.rb +102 -0
- data/test/test_generate_loc_drop.rb +80 -0
- data/test/test_generate_localization_file.rb +91 -0
- data/test/test_output_processor.rb +85 -0
- data/test/test_placeholders.rb +84 -0
- 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 +46 -0
- data/test/twine_test.rb +48 -0
- metadata +179 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'command_test'
|
2
|
+
|
3
|
+
class TestGenerateAllLocalizationFiles < CommandTest
|
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
|
9
|
+
|
10
|
+
unless twine_file
|
11
|
+
twine_file = build_twine_file 'en', 'es' do
|
12
|
+
add_section 'Section' do
|
13
|
+
add_definition key: 'value'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Twine::Runner.new(options, twine_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
class TestDoNotCreateFolders < TestGenerateAllLocalizationFiles
|
22
|
+
def new_runner(twine_file = nil)
|
23
|
+
super(false, twine_file)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_fails_if_output_folder_does_not_exist
|
27
|
+
assert_raises Twine::Error do
|
28
|
+
new_runner.generate_all_localization_files
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_does_not_create_language_folders
|
33
|
+
Dir.mkdir File.join @output_dir, 'en.lproj'
|
34
|
+
new_runner.generate_all_localization_files
|
35
|
+
refute File.exists?(File.join(@output_dir, 'es.lproj')), "language folder should not be created"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_prints_empty_file_warnings
|
39
|
+
Dir.mkdir File.join @output_dir, 'en.lproj'
|
40
|
+
empty_twine_file = build_twine_file('en') {}
|
41
|
+
new_runner(empty_twine_file).generate_all_localization_files
|
42
|
+
assert_match "Skipping file at path", Twine::stderr.string
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class TestCreateFolders < TestGenerateAllLocalizationFiles
|
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_localization_files
|
54
|
+
assert File.exists? @output_dir
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_creates_language_folders
|
58
|
+
new_runner.generate_all_localization_files
|
59
|
+
assert File.exists?(File.join(@output_dir, 'en.lproj')), "language folder 'en.lproj' should be created"
|
60
|
+
assert File.exists?(File.join(@output_dir, 'es.lproj')), "language folder 'es.lproj' should be created"
|
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_localization_files
|
66
|
+
|
67
|
+
assert_match "Skipping file at path", Twine::stderr.string
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class TestValidate < CommandTest
|
72
|
+
def new_runner(validate)
|
73
|
+
Dir.mkdir File.join @output_dir, 'values-en'
|
74
|
+
|
75
|
+
options = {}
|
76
|
+
options[:output_path] = @output_dir
|
77
|
+
options[:format] = 'android'
|
78
|
+
options[:validate] = validate
|
79
|
+
|
80
|
+
twine_file = build_twine_file 'en' do
|
81
|
+
add_section 'Section' do
|
82
|
+
add_definition key: 'value'
|
83
|
+
add_definition key: 'value'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
Twine::Runner.new(options, twine_file)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_does_not_validate_twine_file
|
91
|
+
prepare_mock_formatter Twine::Formatters::Android
|
92
|
+
|
93
|
+
new_runner(false).generate_all_localization_files
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_validates_twine_file_if_validate
|
97
|
+
assert_raises Twine::Error do
|
98
|
+
new_runner(true).generate_all_localization_files
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'command_test'
|
2
|
+
|
3
|
+
class TestGenerateLocDrop < CommandTest
|
4
|
+
def new_runner(twine_file = nil)
|
5
|
+
options = {}
|
6
|
+
options[:output_path] = @output_path
|
7
|
+
options[:format] = 'apple'
|
8
|
+
|
9
|
+
unless twine_file
|
10
|
+
twine_file = build_twine_file 'en', 'fr' do
|
11
|
+
add_section 'Section' do
|
12
|
+
add_definition key: 'value'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Twine::Runner.new(options, twine_file)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_generates_zip_file
|
21
|
+
new_runner.generate_loc_drop
|
22
|
+
|
23
|
+
assert File.exists?(@output_path), "zip file should exist"
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_zip_file_structure
|
27
|
+
new_runner.generate_loc_drop
|
28
|
+
|
29
|
+
names = []
|
30
|
+
Zip::File.open(@output_path) do |zipfile|
|
31
|
+
zipfile.each do |entry|
|
32
|
+
names << entry.name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
assert_equal ['Locales/', 'Locales/en.strings', 'Locales/fr.strings'], names
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_uses_formatter
|
39
|
+
formatter = prepare_mock_formatter Twine::Formatters::Apple
|
40
|
+
formatter.expects(:format_file).twice
|
41
|
+
|
42
|
+
new_runner.generate_loc_drop
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_prints_empty_file_warnings
|
46
|
+
empty_twine_file = build_twine_file('en') {}
|
47
|
+
new_runner(empty_twine_file).generate_loc_drop
|
48
|
+
assert_match "Skipping file", Twine::stderr.string
|
49
|
+
end
|
50
|
+
|
51
|
+
class TestValidate < CommandTest
|
52
|
+
def new_runner(validate)
|
53
|
+
options = {}
|
54
|
+
options[:output_path] = @output_path
|
55
|
+
options[:format] = 'android'
|
56
|
+
options[:validate] = validate
|
57
|
+
|
58
|
+
twine_file = build_twine_file 'en' do
|
59
|
+
add_section 'Section' do
|
60
|
+
add_definition key: 'value'
|
61
|
+
add_definition key: 'value'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Twine::Runner.new(options, twine_file)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_does_not_validate_twine_file
|
69
|
+
prepare_mock_formatter Twine::Formatters::Android
|
70
|
+
|
71
|
+
new_runner(false).generate_loc_drop
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_validates_twine_file_if_validate
|
75
|
+
assert_raises Twine::Error do
|
76
|
+
new_runner(true).generate_loc_drop
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'command_test'
|
2
|
+
|
3
|
+
class TestGenerateLocalizationFile < CommandTest
|
4
|
+
def new_runner(language, file)
|
5
|
+
options = {}
|
6
|
+
options[:output_path] = File.join(@output_dir, file) if file
|
7
|
+
options[:languages] = language if language
|
8
|
+
|
9
|
+
twine_file = Twine::TwineFile.new
|
10
|
+
twine_file.language_codes.concat KNOWN_LANGUAGES
|
11
|
+
|
12
|
+
Twine::Runner.new(options, twine_file)
|
13
|
+
end
|
14
|
+
|
15
|
+
def prepare_mock_format_file_formatter(formatter_class)
|
16
|
+
formatter = prepare_mock_formatter(formatter_class)
|
17
|
+
formatter.expects(:format_file).returns(true)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_deducts_android_format_from_output_path
|
21
|
+
prepare_mock_format_file_formatter Twine::Formatters::Android
|
22
|
+
|
23
|
+
new_runner('fr', 'fr.xml').generate_localization_file
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_deducts_apple_format_from_output_path
|
27
|
+
prepare_mock_format_file_formatter Twine::Formatters::Apple
|
28
|
+
|
29
|
+
new_runner('fr', 'fr.strings').generate_localization_file
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_deducts_jquery_format_from_output_path
|
33
|
+
prepare_mock_format_file_formatter Twine::Formatters::JQuery
|
34
|
+
|
35
|
+
new_runner('fr', 'fr.json').generate_localization_file
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_deducts_gettext_format_from_output_path
|
39
|
+
prepare_mock_format_file_formatter Twine::Formatters::Gettext
|
40
|
+
|
41
|
+
new_runner('fr', 'fr.po').generate_localization_file
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_deducts_language_from_output_path
|
45
|
+
random_language = KNOWN_LANGUAGES.sample
|
46
|
+
formatter = prepare_mock_formatter Twine::Formatters::Android
|
47
|
+
formatter.expects(:format_file).with(random_language).returns(true)
|
48
|
+
|
49
|
+
new_runner(nil, "#{random_language}.xml").generate_localization_file
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_returns_error_if_nothing_written
|
53
|
+
formatter = prepare_mock_formatter Twine::Formatters::Android
|
54
|
+
formatter.expects(:format_file).returns(false)
|
55
|
+
|
56
|
+
assert_raises Twine::Error do
|
57
|
+
new_runner('fr', 'fr.xml').generate_localization_file
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class TestValidate < CommandTest
|
62
|
+
def new_runner(validate)
|
63
|
+
options = {}
|
64
|
+
options[:output_path] = @output_path
|
65
|
+
options[:languages] = ['en']
|
66
|
+
options[:format] = 'android'
|
67
|
+
options[:validate] = validate
|
68
|
+
|
69
|
+
twine_file = build_twine_file 'en' do
|
70
|
+
add_section 'Section' do
|
71
|
+
add_definition key: 'value'
|
72
|
+
add_definition key: 'value'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
Twine::Runner.new(options, twine_file)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_does_not_validate_twine_file
|
80
|
+
prepare_mock_formatter Twine::Formatters::Android
|
81
|
+
|
82
|
+
new_runner(false).generate_localization_file
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_validates_twine_file_if_validate
|
86
|
+
assert_raises Twine::Error do
|
87
|
+
new_runner(true).generate_localization_file
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'twine_test'
|
2
|
+
|
3
|
+
class TestOutputProcessor < TwineTest
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
|
7
|
+
@twine_file = build_twine_file 'en', 'fr' do
|
8
|
+
add_section 'Section' do
|
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
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_includes_all_keys_by_default
|
18
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, {})
|
19
|
+
result = processor.process('en')
|
20
|
+
|
21
|
+
assert_equal %w(key1 key2 key3 key4), result.definitions_by_key.keys.sort
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_filter_by_tag
|
25
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { tags: [['tag1']] })
|
26
|
+
result = processor.process('en')
|
27
|
+
|
28
|
+
assert_equal %w(key1 key2), result.definitions_by_key.keys.sort
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_filter_by_multiple_tags
|
32
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { tags: [['tag1', 'tag2']] })
|
33
|
+
result = processor.process('en')
|
34
|
+
|
35
|
+
assert_equal %w(key1 key2 key3), result.definitions_by_key.keys.sort
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_filter_untagged
|
39
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { tags: [['tag1']], untagged: true })
|
40
|
+
result = processor.process('en')
|
41
|
+
|
42
|
+
assert_equal %w(key1 key2 key4), result.definitions_by_key.keys.sort
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_include_translated
|
46
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { include: :translated })
|
47
|
+
result = processor.process('fr')
|
48
|
+
|
49
|
+
assert_equal %w(key4), result.definitions_by_key.keys.sort
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_include_untranslated
|
53
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, { include: :untranslated })
|
54
|
+
result = processor.process('fr')
|
55
|
+
|
56
|
+
assert_equal %w(key1 key2 key3), result.definitions_by_key.keys.sort
|
57
|
+
end
|
58
|
+
|
59
|
+
class TranslationFallback < TwineTest
|
60
|
+
def setup
|
61
|
+
super
|
62
|
+
|
63
|
+
@twine_file = build_twine_file 'en', 'fr', 'de' do
|
64
|
+
add_section 'Section' do
|
65
|
+
add_definition key1: { en: 'value1-en', fr: 'value1-fr' }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_fallback_to_default_language
|
71
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, {})
|
72
|
+
result = processor.process('de')
|
73
|
+
|
74
|
+
assert_equal 'value1-en', result.definitions_by_key['key1'].translations['de']
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_fallback_to_developer_language
|
78
|
+
processor = Twine::Processors::OutputProcessor.new(@twine_file, {developer_language: 'fr'})
|
79
|
+
result = processor.process('de')
|
80
|
+
|
81
|
+
assert_equal 'value1-fr', result.definitions_by_key['key1'].translations['de']
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'twine_test'
|
2
|
+
|
3
|
+
class PlaceholderTest < TwineTest
|
4
|
+
def assert_starts_with(prefix, value)
|
5
|
+
msg = message(nil) { "Expected #{mu_pp(value)} to start with #{mu_pp(prefix)}" }
|
6
|
+
assert value.start_with?(prefix), msg
|
7
|
+
end
|
8
|
+
|
9
|
+
def placeholder(type = nil)
|
10
|
+
# %[parameter][flags][width][.precision][length]type (see https://en.wikipedia.org/wiki/Printf_format_string#Format_placeholder_specification)
|
11
|
+
lucky = lambda { rand > 0.5 }
|
12
|
+
placeholder = '%'
|
13
|
+
placeholder += (rand * 20).to_i.to_s + '$' if lucky.call
|
14
|
+
placeholder += '-+ 0#'.chars.to_a.sample if lucky.call
|
15
|
+
placeholder += (0.upto(20).map(&:to_s) << "*").sample if lucky.call
|
16
|
+
placeholder += '.' + (0.upto(20).map(&:to_s) << "*").sample if lucky.call
|
17
|
+
placeholder += %w(h hh l ll L z j t).sample if lucky.call
|
18
|
+
placeholder += type || 'diufFeEgGxXocpaA'.chars.to_a.sample # this does not contain s or @ because strings are a special case
|
19
|
+
end
|
20
|
+
|
21
|
+
class ToAndroid < PlaceholderTest
|
22
|
+
def to_android(value)
|
23
|
+
Twine::Placeholders.convert_placeholders_from_twine_to_android(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_replaces_string_placeholder
|
27
|
+
placeholder = placeholder('@')
|
28
|
+
expected = placeholder
|
29
|
+
expected[-1] = 's'
|
30
|
+
assert_equal "some #{expected} value", to_android("some #{placeholder} value")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_does_not_change_regular_at_signs
|
34
|
+
input = "some @ more @@ signs @"
|
35
|
+
assert_equal input, to_android(input)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_does_not_modify_single_percent_signs
|
39
|
+
assert_equal "some % value", to_android("some % value")
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_escapes_single_percent_signs_if_placeholder_present
|
43
|
+
assert_starts_with "some %% v", to_android("some % value #{placeholder}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_does_not_modify_double_percent_signs
|
47
|
+
assert_equal "some %% value", to_android("some %% value")
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_does_not_modify_double_percent_signs_if_placeholder_present
|
51
|
+
assert_starts_with "some %% v", to_android("some %% value #{placeholder}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_does_not_modify_single_placeholder
|
55
|
+
input = "some #{placeholder} text"
|
56
|
+
assert_equal input, to_android(input)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_numbers_multiple_placeholders
|
60
|
+
assert_equal "first %1$d second %2$f", to_android("first %d second %f")
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_does_not_modify_numbered_placeholders
|
64
|
+
input = "second %2$f first %1$d"
|
65
|
+
assert_equal input, to_android(input)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_raises_an_error_when_mixing_numbered_and_non_numbered_placeholders
|
69
|
+
assert_raises Twine::Error do
|
70
|
+
to_android("some %d second %2$f")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class FromAndroid < PlaceholderTest
|
76
|
+
def from_android(value)
|
77
|
+
Twine::Placeholders.convert_placeholders_from_android_to_twine(value)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_replaces_string_placeholder
|
81
|
+
assert_equal "some %@ value", from_android("some %s value")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'twine_test'
|
2
|
+
|
3
|
+
class TestTwineDefinition < TwineTest
|
4
|
+
class TestTags < TwineTest
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
@definition = Twine::TwineDefinition.new 'key'
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_include_untagged
|
11
|
+
assert @definition.matches_tags?([[rand(100000).to_s]], true)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_matches_no_given_tags
|
15
|
+
assert @definition.matches_tags?([], false)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_matches_tag
|
19
|
+
@definition.tags = ['tag1']
|
20
|
+
|
21
|
+
assert @definition.matches_tags?([['tag1']], false)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_matches_any_tag
|
25
|
+
@definition.tags = ['tag1']
|
26
|
+
|
27
|
+
assert @definition.matches_tags?([['tag0', 'tag1', 'tag2']], false)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_matches_all_tags
|
31
|
+
@definition.tags = ['tag1', 'tag2']
|
32
|
+
|
33
|
+
assert @definition.matches_tags?([['tag1'], ['tag2']], false)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_does_not_match_all_tags
|
37
|
+
@definition.tags = ['tag1']
|
38
|
+
|
39
|
+
refute @definition.matches_tags?([['tag1'], ['tag2']], false)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_does_not_match_excluded_tag
|
43
|
+
@definition.tags = ['tag1']
|
44
|
+
|
45
|
+
refute @definition.matches_tags?([['~tag1']], false)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_matches_excluded_tag
|
49
|
+
@definition.tags = ['tag2']
|
50
|
+
|
51
|
+
assert @definition.matches_tags?([['~tag1']], false)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_complex_rules
|
55
|
+
@definition.tags = ['tag1', 'tag2', 'tag3']
|
56
|
+
|
57
|
+
assert @definition.matches_tags?([['tag1']], false)
|
58
|
+
assert @definition.matches_tags?([['tag1', 'tag4']], false)
|
59
|
+
assert @definition.matches_tags?([['tag1'], ['tag2'], ['tag3']], false)
|
60
|
+
refute @definition.matches_tags?([['tag1'], ['tag4']], false)
|
61
|
+
|
62
|
+
assert @definition.matches_tags?([['tag4', '~tag5']], false)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class TestReferences < TwineTest
|
67
|
+
def setup
|
68
|
+
super
|
69
|
+
|
70
|
+
@reference = Twine::TwineDefinition.new 'reference-key'
|
71
|
+
@reference.comment = 'reference comment'
|
72
|
+
@reference.tags = ['ref1']
|
73
|
+
@reference.translations['en'] = 'ref-value'
|
74
|
+
|
75
|
+
@definition = Twine::TwineDefinition.new 'key'
|
76
|
+
@definition.reference_key = @reference.key
|
77
|
+
@definition.reference = @reference
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_reference_comment_used
|
81
|
+
assert_equal 'reference comment', @definition.comment
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_reference_comment_override
|
85
|
+
@definition.comment = 'definition comment'
|
86
|
+
|
87
|
+
assert_equal 'definition comment', @definition.comment
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_reference_tags_used
|
91
|
+
assert @definition.matches_tags?([['ref1']], false)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_reference_tags_override
|
95
|
+
@definition.tags = ['tag1']
|
96
|
+
|
97
|
+
refute @definition.matches_tags?([['ref1']], false)
|
98
|
+
assert @definition.matches_tags?([['tag1']], false)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_reference_translation_used
|
102
|
+
assert_equal 'ref-value', @definition.translation_for_lang('en')
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_reference_translation_override
|
106
|
+
@definition.translations['en'] = 'value'
|
107
|
+
|
108
|
+
assert_equal 'value', @definition.translation_for_lang('en')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|