vocab 0.0.2 → 0.0.3
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.
- data/.gitignore +2 -1
- data/CHANGELOG.md +4 -0
- data/MIT-LICENSE +7 -0
- data/README.md +66 -14
- data/bin/vocab +1 -1
- data/lib/vocab/application.rb +7 -5
- data/lib/vocab/extractor/android.rb +31 -14
- data/lib/vocab/extractor/base.rb +27 -11
- data/lib/vocab/extractor/rails.rb +16 -6
- data/lib/vocab/merger/android.rb +48 -15
- data/lib/vocab/merger/base.rb +0 -6
- data/lib/vocab/translator/android.rb +67 -9
- data/lib/vocab/validator/android.rb +2 -2
- data/lib/vocab/validator/base.rb +7 -1
- data/lib/vocab/validator/rails.rb +1 -1
- data/lib/vocab/version.rb +1 -1
- data/spec/data/android/locales/values/strings.xml +11 -0
- data/spec/data/android/locales/values-es/strings.xml +5 -0
- data/spec/data/android/translations/values-es/es-string-file.xml +11 -0
- data/spec/data/android/write.xml +1 -0
- data/spec/data/android/write_plurals.xml +14 -0
- data/spec/data/rails/locales/en.yml +4 -0
- data/spec/extractor/android_spec.rb +47 -26
- data/spec/extractor/base_spec.rb +25 -8
- data/spec/extractor/rails_spec.rb +23 -20
- data/spec/merger/android_spec.rb +78 -25
- data/spec/merger/base_spec.rb +0 -1
- data/spec/merger/rails_spec.rb +1 -2
- data/spec/spec_helper.rb +8 -5
- data/spec/support/matchers.rb +25 -0
- data/spec/translator/android_spec.rb +45 -2
- data/spec/translator/rails_spec.rb +28 -24
- data/spec/validator/android_spec.rb +2 -2
- data/spec/validator/base_spec.rb +23 -0
- data/spec/validator/rails_spec.rb +6 -6
- data/vocab.gemspec +1 -0
- metadata +23 -8
@@ -4,4 +4,15 @@
|
|
4
4
|
<string name="delete">La función Child Lock</string>
|
5
5
|
<string name="pd_app_name">el Panel para padres bien</string>
|
6
6
|
<string name="translator_cruft">Malo</string>
|
7
|
+
<string name="apostrophe">Translator's evil apostrophe don\'t care</string>
|
8
|
+
|
9
|
+
<plurals name="user_count">
|
10
|
+
<item quantity="one">1 usuario</item>
|
11
|
+
<item quantity="many">%d usuarios</item>
|
12
|
+
</plurals>
|
13
|
+
|
14
|
+
<plurals name="fish_count">
|
15
|
+
<item quantity="one">1 pescado</item>
|
16
|
+
<item quantity="many">%d peces</item>
|
17
|
+
</plurals>
|
7
18
|
</resources>
|
data/spec/data/android/write.xml
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<resources>
|
3
|
+
<string name="apostrophe">Translator\'s evil apostrophe don\'t care</string>
|
3
4
|
<string name="app_name">Kid Mode</string>
|
4
5
|
<string name="delete">La funci&#xF3;n Child Lock</string>
|
5
6
|
<string name="pd_app_name">Parent Dashboard</string>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<resources>
|
3
|
+
<string name="app_name">Kid Mode</string>
|
4
|
+
<string name="delete">La funci&#xF3;n Child Lock</string>
|
5
|
+
<string name="pd_app_name">Parent Dashboard</string>
|
6
|
+
<plurals name="deer">
|
7
|
+
<item quantity="one">1 deer</item>
|
8
|
+
<item quantity="other">2 deer</item>
|
9
|
+
</plurals>
|
10
|
+
<plurals name="users">
|
11
|
+
<item quantity="one">1 user</item>
|
12
|
+
<item quantity="other">2 users</item>
|
13
|
+
</plurals>
|
14
|
+
</resources>
|
@@ -6,21 +6,22 @@ describe "Vocab::Extractor::Android" do
|
|
6
6
|
@locale = "#{vocab_root}/spec/data/android/locales/values/strings.xml"
|
7
7
|
end
|
8
8
|
|
9
|
-
describe '
|
9
|
+
describe 'current_strings' do
|
10
10
|
|
11
11
|
it "extracts hash of current string translations" do
|
12
|
-
actual = Vocab::Extractor::Android.
|
12
|
+
actual = Vocab::Extractor::Android.current_strings( @locale )
|
13
13
|
actual.should eql( { "app_name" =>"Kid Mode",
|
14
14
|
"delete" =>"Delete",
|
15
15
|
"cancel" =>"Cancel",
|
16
16
|
"app_current"=>"current",
|
17
17
|
"pd_app_name"=>"Parent Dashboard",
|
18
|
-
"not_in_es" =>"This key not in spanish",
|
18
|
+
"not_in_es" =>"This key not in spanish",
|
19
|
+
"debug_key" =>"Should be ignored" } )
|
19
20
|
end
|
20
21
|
|
21
22
|
end
|
22
23
|
|
23
|
-
describe '
|
24
|
+
describe 'previous_strings' do
|
24
25
|
|
25
26
|
before( :each ) do
|
26
27
|
Dir.chdir( vocab_root )
|
@@ -32,7 +33,7 @@ describe "Vocab::Extractor::Android" do
|
|
32
33
|
end
|
33
34
|
|
34
35
|
it "extracts hash of previous string translations" do
|
35
|
-
actual = Vocab::Extractor::Android.
|
36
|
+
actual = Vocab::Extractor::Android.previous_strings( @locale )
|
36
37
|
actual.should eql( { 'app_name' => 'Kid Mode',
|
37
38
|
'pd_app_name' => 'Parent Dashboard',
|
38
39
|
'app_current' => 'current' } )
|
@@ -40,13 +41,46 @@ describe "Vocab::Extractor::Android" do
|
|
40
41
|
|
41
42
|
end
|
42
43
|
|
44
|
+
describe 'current_plurals' do
|
45
|
+
|
46
|
+
it "extracts the plural definitions from the strings file" do
|
47
|
+
expected = { "user_count" => { "one" => "1 user",
|
48
|
+
"many" => "%d users" },
|
49
|
+
"fish_count" => { "one" => "1 fish",
|
50
|
+
"many" => "%d fish" } }
|
51
|
+
Vocab::Extractor::Android.current_plurals( @locale ).should eql( expected )
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'previous_plurals' do
|
57
|
+
|
58
|
+
before( :each ) do
|
59
|
+
Dir.chdir( vocab_root )
|
60
|
+
end
|
61
|
+
|
62
|
+
before( :each ) do
|
63
|
+
@sha = '618e87b6a53e8fc216f046e51b1606313052bf75'
|
64
|
+
Vocab.settings.stub!( :last_translation ).and_return( @sha )
|
65
|
+
end
|
66
|
+
|
67
|
+
it "extracts hash of previous string translations" do
|
68
|
+
actual = Vocab::Extractor::Android.previous_plurals( @locale )
|
69
|
+
actual.should eql( { "fish_count" => { "one" => "1 fishes",
|
70
|
+
"many" => "%d fish" } } )
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
43
75
|
describe 'write_full' do
|
44
76
|
|
45
77
|
it 'writes the full translation to the correct xml file' do
|
46
|
-
|
78
|
+
strings = { 'foo' => 'bar' }
|
79
|
+
plurals = { 'users' => { 'one' => '1 user',
|
80
|
+
'other' => '2 users' } }
|
47
81
|
Vocab::Translator::Android.should_receive( :write ).
|
48
|
-
with(
|
49
|
-
Vocab::Extractor::Android.write_full(
|
82
|
+
with( strings, plurals, "#{vocab_root}/strings.full.xml" )
|
83
|
+
Vocab::Extractor::Android.write_full( strings, plurals )
|
50
84
|
end
|
51
85
|
|
52
86
|
end
|
@@ -54,25 +88,12 @@ describe "Vocab::Extractor::Android" do
|
|
54
88
|
describe 'write_diff' do
|
55
89
|
|
56
90
|
it 'writes the diff translation to the correct xml file' do
|
57
|
-
|
91
|
+
strings = { 'foo' => 'bar' }
|
92
|
+
plurals = { 'users' => { 'one' => '1 user',
|
93
|
+
'other' => '2 users' } }
|
58
94
|
Vocab::Translator::Android.should_receive( :write ).
|
59
|
-
with(
|
60
|
-
Vocab::Extractor::Android.write_diff(
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
describe 'write' do
|
66
|
-
|
67
|
-
it 'writes the translation to a xml file' do
|
68
|
-
translation = { 'app_name' => 'Kid Mode',
|
69
|
-
'pd_app_name' => 'Parent Dashboard',
|
70
|
-
'delete' => "La función Child Lock" }
|
71
|
-
path = "#{vocab_root}/spec/tmp/strings.xml"
|
72
|
-
Vocab::Translator::Android.write( translation, path )
|
73
|
-
should_eql_file( File.open( path ) { |f| f.read },
|
74
|
-
"spec/data/android/write.xml" )
|
75
|
-
File.delete( path )
|
95
|
+
with( strings, plurals, "#{vocab_root}/strings.diff.xml" )
|
96
|
+
Vocab::Extractor::Android.write_diff( strings, plurals )
|
76
97
|
end
|
77
98
|
|
78
99
|
end
|
data/spec/extractor/base_spec.rb
CHANGED
@@ -36,6 +36,20 @@ describe "Vocab::Extractor::Base" do
|
|
36
36
|
:"en.models.product.id_126.name"=>"This is new"}
|
37
37
|
end
|
38
38
|
|
39
|
+
it "finds new plural definitions" do
|
40
|
+
@current = { 'users' => {}, 'fish' => {} }
|
41
|
+
@previous = { 'users' => {} }
|
42
|
+
diff = Vocab::Extractor::Base.diff( @previous, @current )
|
43
|
+
diff.should == { 'fish' => {} }
|
44
|
+
end
|
45
|
+
|
46
|
+
it "finds updated plural definitions" do
|
47
|
+
@current = { 'users' => { 'one' => '1 user', 'other' => '%d users' }, 'fish' => {} }
|
48
|
+
@previous = { 'users' => { 'one' => '1 person', 'other' => '%d users' }, 'fish' => {} }
|
49
|
+
diff = Vocab::Extractor::Base.diff( @previous, @current )
|
50
|
+
diff.should == { 'users' => { 'one' => '1 user', 'other' => '%d users' } }
|
51
|
+
end
|
52
|
+
|
39
53
|
end
|
40
54
|
|
41
55
|
describe "extract" do
|
@@ -49,11 +63,14 @@ describe "Vocab::Extractor::Base" do
|
|
49
63
|
it "extracts the strings that need to be translated into a yml file" do
|
50
64
|
current = { 1 => 5, 3 => 4 }
|
51
65
|
previous = { 1 => 2 }
|
52
|
-
Vocab::Extractor::Base.should_receive( :
|
53
|
-
Vocab::Extractor::Base.should_receive( :
|
54
|
-
Vocab::Extractor::Base.should_receive( :
|
55
|
-
Vocab::Extractor::Base.should_receive( :
|
66
|
+
Vocab::Extractor::Base.should_receive( :current_strings ).and_return( current )
|
67
|
+
Vocab::Extractor::Base.should_receive( :previous_strings ).and_return( previous )
|
68
|
+
Vocab::Extractor::Base.should_receive( :current_plurals ).and_return( {} )
|
69
|
+
Vocab::Extractor::Base.should_receive( :previous_plurals ).and_return( {} )
|
70
|
+
Vocab::Extractor::Base.should_receive( :write_diff ).with( { 1 => 5, 3 => 4 }, {}, @diff_path )
|
71
|
+
Vocab::Extractor::Base.should_receive( :write_full ).with( current, {}, @full_path )
|
56
72
|
Vocab::Extractor::Base.should_receive( :mkdir_examples )
|
73
|
+
Vocab::Extractor::Base.should_receive( :update_settings )
|
57
74
|
Vocab::Extractor::Base.extract( @diff_path, @full_path )
|
58
75
|
end
|
59
76
|
|
@@ -68,22 +85,22 @@ describe "Vocab::Extractor::Base" do
|
|
68
85
|
|
69
86
|
it "returns the contents of a file from a specific git version" do
|
70
87
|
contents = Vocab::Extractor::Base.previous_file( @path, 'a19f7c5c28c1158792a966c0d2153a04490dd35e' )
|
71
|
-
|
88
|
+
contents.should eql_file( 'spec/data/android/previous.xml' )
|
72
89
|
|
73
90
|
contents = Vocab::Extractor::Base.previous_file( @path, '0533bcd9a304cd6e74d6a56959dbcabd57b2f1b9' )
|
74
|
-
|
91
|
+
contents.should eql_file( 'spec/data/android/current.xml' )
|
75
92
|
end
|
76
93
|
|
77
94
|
it "returns the correct contents when a full path is specified" do
|
78
95
|
contents = Vocab::Extractor::Base.previous_file( "#{vocab_root}/#{@path}", 'a19f7c5c28c1158792a966c0d2153a04490dd35e' )
|
79
|
-
|
96
|
+
contents.should eql_file( 'spec/data/android/previous.xml' )
|
80
97
|
end
|
81
98
|
|
82
99
|
it "returns the contents of a file when in a subdir of the git directory" do
|
83
100
|
Dir.chdir( "spec" )
|
84
101
|
@path = "data/android/locales/strings.xml"
|
85
102
|
contents = Vocab::Extractor::Base.previous_file( @path, 'a19f7c5c28c1158792a966c0d2153a04490dd35e' )
|
86
|
-
|
103
|
+
contents.should eql_file( 'spec/data/android/previous.xml' )
|
87
104
|
end
|
88
105
|
|
89
106
|
end
|
@@ -7,7 +7,7 @@ describe "Vocab::Extractor::Rails" do
|
|
7
7
|
it 'writes the full en translation to a file' do
|
8
8
|
translation = { :en => { :full => 'translation' } }
|
9
9
|
path = "#{vocab_root}/spec/tmp/en.full.yml"
|
10
|
-
Vocab::Extractor::Rails.write_full( translation, path )
|
10
|
+
Vocab::Extractor::Rails.write_full( translation, {}, path )
|
11
11
|
YAML.load_file( path ).should eql( translation )
|
12
12
|
File.delete( path )
|
13
13
|
end
|
@@ -27,7 +27,7 @@ describe "Vocab::Extractor::Rails" do
|
|
27
27
|
|
28
28
|
end
|
29
29
|
|
30
|
-
describe "
|
30
|
+
describe "previous_strings" do
|
31
31
|
|
32
32
|
before( :each ) do
|
33
33
|
@last_translation = '5ab8cf4d081d7ba1d5f020118dd00c3ea2d0437a'
|
@@ -37,7 +37,7 @@ describe "Vocab::Extractor::Rails" do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "creates a hash of the english translation strings from the last translation" do
|
40
|
-
actual = Vocab::Extractor::Rails.
|
40
|
+
actual = Vocab::Extractor::Rails.previous_strings( @locales_root )
|
41
41
|
expected = { :"en.models.product.id_36.description" =>"Polarized and lazer resistant",
|
42
42
|
:"en.marketing.banner" =>"This product is so good",
|
43
43
|
:"en.models.product.id_36.name" =>"This nested value has changed",
|
@@ -54,13 +54,13 @@ describe "Vocab::Extractor::Rails" do
|
|
54
54
|
it 'creates a tmp folder if one does not exist' do
|
55
55
|
dir = "#{vocab_root}/tmp/last_translation"
|
56
56
|
FileUtils.rm_rf( "#{vocab_root}/tmp/last_translation" )
|
57
|
-
Vocab::Extractor::Rails.
|
57
|
+
Vocab::Extractor::Rails.previous_strings( @locales_root )
|
58
58
|
File.exists?( dir ).should be_true
|
59
59
|
end
|
60
60
|
|
61
61
|
end
|
62
62
|
|
63
|
-
describe "
|
63
|
+
describe "current_strings" do
|
64
64
|
|
65
65
|
before( :each ) do
|
66
66
|
Dir.chdir( vocab_root )
|
@@ -68,19 +68,21 @@ describe "Vocab::Extractor::Rails" do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it "creates a hash of the english translation strings currently in the config" do
|
71
|
-
actual = Vocab::Extractor::Rails.
|
72
|
-
expected = {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
71
|
+
actual = Vocab::Extractor::Rails.current_strings( @locales_root )
|
72
|
+
expected = {:"en.marketing.banner"=>"This product is so good",
|
73
|
+
:"en.dashboard.chart"=>"This value has changed",
|
74
|
+
:"en.dashboard.details"=>"This key/value has been added",
|
75
|
+
:"en.menu.first"=>"First menu item",
|
76
|
+
:"en.menu.second"=>"Second menu item",
|
77
|
+
:"en.not_in_es"=>"This key not in spanish",
|
78
|
+
:"en.users.one"=>"1 user",
|
79
|
+
:"en.users.other"=>"%{count} users",
|
80
|
+
:"en.models.product.id_125.description"=>"Green with megawatts",
|
81
|
+
:"en.models.product.id_125.name"=>"Lazer",
|
82
|
+
:"en.models.product.id_36.description"=>"Polarized and lazer resistant",
|
83
|
+
:"en.models.product.id_36.name"=>"This nested value has changed",
|
84
|
+
:"en.models.product.id_55.description"=>"A new nested description",
|
85
|
+
:"en.models.product.id_55.name"=>"a new nested name"}
|
84
86
|
actual.should eql( expected )
|
85
87
|
end
|
86
88
|
|
@@ -94,8 +96,9 @@ describe "Vocab::Extractor::Rails" do
|
|
94
96
|
end
|
95
97
|
|
96
98
|
it "extracts the strings that need to be translated into a yml file" do
|
97
|
-
Vocab::Extractor::Rails.should_receive( :
|
98
|
-
Vocab::Extractor::Rails.should_receive( :
|
99
|
+
Vocab::Extractor::Rails.should_receive( :current_strings ).and_return( { :en => { 1 => 5, 3 => 4 } } )
|
100
|
+
Vocab::Extractor::Rails.should_receive( :previous_strings ).and_return( { :en => { 1 => 2 } } )
|
101
|
+
Vocab.settings.should_receive( :update_translation )
|
99
102
|
Vocab::Extractor::Rails.extract( @diff_path, @full_path )
|
100
103
|
YAML.load_file( @diff_path ).should == { :en => { 1 => 5, 3 => 4 } }
|
101
104
|
|
data/spec/merger/android_spec.rb
CHANGED
@@ -27,7 +27,6 @@ describe "Vocab::Merger::Android" do
|
|
27
27
|
describe "merge" do
|
28
28
|
|
29
29
|
before( :each ) do
|
30
|
-
Vocab.settings.should_receive( :update_translation )
|
31
30
|
@merger = Vocab::Merger::Android.new( @merge_dir, @update_dir )
|
32
31
|
@merger.merge
|
33
32
|
end
|
@@ -47,66 +46,120 @@ describe "Vocab::Merger::Android" do
|
|
47
46
|
@file = "#{@merge_dir}/values-es/strings.xml"
|
48
47
|
@merger = Vocab::Merger::Android.new( @merge_dir, @update_dir )
|
49
48
|
@merger.merge_file( @file )
|
50
|
-
@merged = Vocab::Translator::Android.hash_from_xml( @file )
|
51
49
|
end
|
52
50
|
|
53
|
-
|
54
|
-
@merged['pd_app_name'].should eql( 'el Panel para padres bien' )
|
55
|
-
end
|
51
|
+
context "strings" do
|
56
52
|
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
before( :each ) do
|
54
|
+
@merged = Vocab::Translator::Android.hash_from_xml( @file )
|
55
|
+
end
|
60
56
|
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
it "merges updated android translations" do
|
58
|
+
@merged['pd_app_name'].should eql( 'el Panel para padres bien' )
|
59
|
+
end
|
64
60
|
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
it "integrates new android translations" do
|
62
|
+
@merged['cancel'].should eql( 'Cancelar' )
|
63
|
+
end
|
64
|
+
|
65
|
+
it "properly encodes html entities" do
|
66
|
+
@merged['delete'].should eql( "La función Child Lock" )
|
67
|
+
end
|
68
|
+
|
69
|
+
it "ignores key accidentally introduced by the translators into android translations" do
|
70
|
+
@merged['translator_cruft'].should be( nil )
|
71
|
+
end
|
72
|
+
|
73
|
+
it "retains unchanged android translations" do
|
74
|
+
@merged['app_name'].should eql( 'Modo Niños' )
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does not include keys where there is no translation' do
|
78
|
+
@merged['not_in_es'].should be( nil )
|
79
|
+
end
|
68
80
|
|
69
|
-
it "retains unchanged android translations" do
|
70
|
-
@merged['app_name'].should eql( 'Modo Niños' )
|
71
81
|
end
|
72
82
|
|
73
|
-
|
74
|
-
|
83
|
+
context "strings" do
|
84
|
+
|
85
|
+
before( :each ) do
|
86
|
+
@merged = Vocab::Translator::Android.plurals_from_xml( @file )
|
87
|
+
end
|
88
|
+
|
89
|
+
it "includes plurals where an item is updated" do
|
90
|
+
@merged[ 'fish_count' ].should eql( { 'one' => '1 pescado', 'many' => '%d peces' } )
|
91
|
+
end
|
92
|
+
|
93
|
+
it "includes new plural definition" do
|
94
|
+
@merged[ 'user_count' ].should eql( {"one"=>"1 usuario", "many"=>"%d usuarios"} )
|
95
|
+
end
|
75
96
|
end
|
76
97
|
|
77
98
|
end
|
78
99
|
|
79
|
-
describe '
|
100
|
+
describe 'string_keys' do
|
80
101
|
|
81
102
|
it 'fetches the english keys' do
|
82
103
|
merger = Vocab::Merger::Android.new( @merge_dir )
|
83
104
|
keys = ["app_name", "delete", "cancel", "app_current", "not_in_es", "pd_app_name"]
|
84
|
-
merger.
|
105
|
+
merger.string_keys.should =~ keys
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'plural_keys' do
|
111
|
+
|
112
|
+
it 'fetches the plural definition keys from the english file' do
|
113
|
+
merger = Vocab::Merger::Android.new( @merge_dir )
|
114
|
+
keys = ["fish_count", "user_count"]
|
115
|
+
merger.plural_keys.should =~ keys
|
85
116
|
end
|
86
117
|
|
87
118
|
end
|
88
119
|
|
89
|
-
describe '
|
120
|
+
describe 'current_strings_for_locale' do
|
90
121
|
|
91
122
|
it 'returns hash of the current translations that match a locale file' do
|
92
123
|
merger = Vocab::Merger::Android.new( @merge_dir )
|
93
124
|
expected = { "app_name" =>"Modo Niños",
|
94
125
|
"app_current"=>"actual",
|
95
126
|
"pd_app_name"=>"el Panel para padres"}
|
96
|
-
merger.
|
127
|
+
merger.current_strings_for_locale( "#{@merge_dir}/values-es/strings.xml" ).should == expected
|
97
128
|
end
|
98
129
|
|
99
130
|
end
|
100
131
|
|
101
|
-
describe '
|
132
|
+
describe 'update_strings_for_locale' do
|
102
133
|
|
103
134
|
it 'returns hash of the updates that match a locale file' do
|
104
135
|
merger = Vocab::Merger::Android.new( @merge_dir, @update_dir )
|
105
136
|
expected = { 'cancel' => 'Cancelar',
|
106
137
|
'delete' => "La función Child Lock",
|
107
138
|
'pd_app_name' => 'el Panel para padres bien',
|
108
|
-
'translator_cruft' => 'Malo'
|
109
|
-
|
139
|
+
'translator_cruft' => 'Malo',
|
140
|
+
'apostrophe' => "Translator\\'s evil apostrophe don\\'t care" }
|
141
|
+
merger.update_strings_for_locale( "#{@merge_dir}/values-es/strings.xml" ).should == expected
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'current_plurals_for_locale' do
|
147
|
+
|
148
|
+
it 'returns hash of the current translations that match a locale file' do
|
149
|
+
merger = Vocab::Merger::Android.new( @merge_dir )
|
150
|
+
expected = { "fish_count" => { "one" => "1 pescado", "many" => "%d peces" } }
|
151
|
+
merger.current_plurals_for_locale( "#{@merge_dir}/values-es/strings.xml" ).should == expected
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
describe 'update_plurals_for_locale' do
|
157
|
+
|
158
|
+
it 'returns hash of the updates that match a locale file' do
|
159
|
+
merger = Vocab::Merger::Android.new( @merge_dir, @update_dir )
|
160
|
+
expected = { "user_count" => { "one" => "1 usuario", "many" => "%d usuarios" },
|
161
|
+
"fish_count" => { "one" => "1 pescado", "many" => "%d peces" } }
|
162
|
+
merger.update_plurals_for_locale( "#{@merge_dir}/values-es/strings.xml" ).should == expected
|
110
163
|
end
|
111
164
|
|
112
165
|
end
|
data/spec/merger/base_spec.rb
CHANGED
data/spec/merger/rails_spec.rb
CHANGED
@@ -89,7 +89,6 @@ describe "Vocab::Merger::Rails" do
|
|
89
89
|
before( :each ) do
|
90
90
|
init_merge_dir
|
91
91
|
@update_dir = "#{vocab_root}/spec/data/rails/translations"
|
92
|
-
Vocab.settings.should_receive( :update_translation )
|
93
92
|
@merger = Vocab::Merger::Rails.new( @merge_dir, @update_dir )
|
94
93
|
@merger.merge
|
95
94
|
end
|
@@ -116,7 +115,7 @@ describe "Vocab::Merger::Rails" do
|
|
116
115
|
it "returns the keys that should be in a file" do
|
117
116
|
path = "#{vocab_root}/spec/data/rails/locales/es.yml"
|
118
117
|
actual = Vocab::Merger::Rails.keys_for_file( path )
|
119
|
-
expected = [:"dashboard.details", :"menu.first", :"dashboard.chart", :"menu.second", :"marketing.banner", :"not_in_es"]
|
118
|
+
expected = [:"dashboard.details", :"menu.first", :"dashboard.chart", :"menu.second", :"marketing.banner", :"not_in_es", :"users.one", :"users.other"]
|
120
119
|
actual.each { |key| expected.should include( key ) }
|
121
120
|
actual.size.should eql( expected.size )
|
122
121
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,6 +6,13 @@ require "vocab"
|
|
6
6
|
require "support/matchers"
|
7
7
|
require "support/shared"
|
8
8
|
|
9
|
+
require 'simplecov'
|
10
|
+
|
11
|
+
SimpleCov.start do
|
12
|
+
coverage_dir 'coverage'
|
13
|
+
add_filter "/spec/"
|
14
|
+
end
|
15
|
+
|
9
16
|
Vocab.ui.silent = true
|
10
17
|
|
11
18
|
RSpec.configure do |config|
|
@@ -16,8 +23,4 @@ def vocab_root
|
|
16
23
|
return File.expand_path( '../..', __FILE__ )
|
17
24
|
end
|
18
25
|
|
19
|
-
|
20
|
-
@tmp = File.open( "#{vocab_root}/#{path}.tmp","wb") { |io| io.write actual }
|
21
|
-
@expected = File.open("#{vocab_root}/#{path}","rb") {|io| io.read }
|
22
|
-
actual.chomp.strip.should eql( @expected.chomp.strip )
|
23
|
-
end
|
26
|
+
|
data/spec/support/matchers.rb
CHANGED
@@ -10,4 +10,29 @@ module Vocab
|
|
10
10
|
#end
|
11
11
|
end
|
12
12
|
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Matcher to compare an in-memory string with a ground truth file.
|
16
|
+
# Exports the actual value as a .tmp file as a side effect.
|
17
|
+
|
18
|
+
RSpec::Matchers.define :eql_file do |expected|
|
19
|
+
|
20
|
+
description do
|
21
|
+
"match the contents of #{expected}"
|
22
|
+
end
|
23
|
+
|
24
|
+
match do |actual|
|
25
|
+
File.open( "#{vocab_root}/#{expected}.tmp","wb" ) { |io| io.write actual }
|
26
|
+
slurped = File.open( "#{vocab_root}/#{expected}","rb" ) {|io| io.read }
|
27
|
+
actual == slurped
|
28
|
+
end
|
29
|
+
|
30
|
+
failure_message_for_should do |actual|
|
31
|
+
"expected that #{actual} would match the contents of #{expected}"
|
32
|
+
end
|
33
|
+
|
34
|
+
failure_message_for_should_not do |actual|
|
35
|
+
"expected that #{actual} would not match the contents of #{expected}"
|
36
|
+
end
|
37
|
+
|
13
38
|
end
|
@@ -2,12 +2,12 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe 'Vocab::Translator::Android' do
|
4
4
|
|
5
|
-
describe '
|
5
|
+
describe 'string_keys' do
|
6
6
|
|
7
7
|
it 'returns the english keys for a locales dir' do
|
8
8
|
locales_dir = "#{vocab_root}/spec/data/android/locales"
|
9
9
|
expected = ["app_name", "delete", "cancel", "app_current", "not_in_es", "pd_app_name"]
|
10
|
-
Vocab::Translator::Android.
|
10
|
+
Vocab::Translator::Android.string_keys( locales_dir ).should =~ expected
|
11
11
|
end
|
12
12
|
|
13
13
|
end
|
@@ -21,4 +21,47 @@ describe 'Vocab::Translator::Android' do
|
|
21
21
|
|
22
22
|
end
|
23
23
|
|
24
|
+
describe 'write' do
|
25
|
+
|
26
|
+
it 'writes the strings to a xml file' do
|
27
|
+
strings = { 'app_name' => 'Kid Mode',
|
28
|
+
'pd_app_name' => 'Parent Dashboard',
|
29
|
+
'delete' => "La función Child Lock",
|
30
|
+
'apostrophe' => "Translator\\'s evil apostrophe don\\'t care"}
|
31
|
+
plurals = {}
|
32
|
+
path = "#{vocab_root}/spec/tmp/strings.xml"
|
33
|
+
Vocab::Translator::Android.write( strings, plurals, path )
|
34
|
+
strings = File.open( path ) { |f| f.read }
|
35
|
+
strings.should eql_file( "spec/data/android/write.xml" )
|
36
|
+
File.delete( path )
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'writes the strings and plurals to a xml file' do
|
40
|
+
strings = { 'app_name' => 'Kid Mode',
|
41
|
+
'pd_app_name' => 'Parent Dashboard',
|
42
|
+
'delete' => "La función Child Lock" }
|
43
|
+
plurals = { 'users' => { 'one' => '1 user',
|
44
|
+
'other' => '2 users' },
|
45
|
+
'deer' => { 'one' => '1 deer',
|
46
|
+
'other' => '2 deer' } }
|
47
|
+
path = "#{vocab_root}/spec/tmp/strings.xml"
|
48
|
+
Vocab::Translator::Android.write( strings, plurals, path )
|
49
|
+
strings = File.open( path ) { |f| f.read }
|
50
|
+
strings.should eql_file( "spec/data/android/write_plurals.xml" )
|
51
|
+
File.delete( path )
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'android resource special cases' do
|
57
|
+
|
58
|
+
it "escapes apostrophes to be compatible with android resources" do
|
59
|
+
hash = Vocab::Translator::Android.hash_from_xml( "#{vocab_root}/spec/data/android/translations/values-es/es-string-file.xml" )
|
60
|
+
hash['apostrophe'].should eql( %q[Translator\'s evil apostrophe don\'t care] )
|
61
|
+
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
24
67
|
end
|