yury-twine 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|