vocab 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,4 +4,15 @@
4
4
  <string name="delete">La funci&oacute;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&apos;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>
@@ -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&amp;#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&amp;#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>
@@ -8,3 +8,7 @@ en:
8
8
  first: First menu item
9
9
  second: Second menu item
10
10
  not_in_es: This key not in spanish
11
+ users:
12
+ one: 1 user
13
+ other: "%{count} users"
14
+
@@ -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 'extract_current' do
9
+ describe 'current_strings' do
10
10
 
11
11
  it "extracts hash of current string translations" do
12
- actual = Vocab::Extractor::Android.extract_current( @locale )
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 'extract_previous' do
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.extract_previous( @locale )
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
- hash = { 'foo' => 'bar' }
78
+ strings = { 'foo' => 'bar' }
79
+ plurals = { 'users' => { 'one' => '1 user',
80
+ 'other' => '2 users' } }
47
81
  Vocab::Translator::Android.should_receive( :write ).
48
- with( hash, "#{vocab_root}/strings.full.xml" )
49
- Vocab::Extractor::Android.write_full( hash )
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
- hash = { 'foo' => 'bar' }
91
+ strings = { 'foo' => 'bar' }
92
+ plurals = { 'users' => { 'one' => '1 user',
93
+ 'other' => '2 users' } }
58
94
  Vocab::Translator::Android.should_receive( :write ).
59
- with( hash, "#{vocab_root}/strings.diff.xml" )
60
- Vocab::Extractor::Android.write_diff( hash )
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&#xF3;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
@@ -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( :extract_current ).and_return( current )
53
- Vocab::Extractor::Base.should_receive( :extract_previous ).and_return( previous )
54
- Vocab::Extractor::Base.should_receive( :write_diff ).with( { 1 => 5, 3 => 4 }, @diff_path )
55
- Vocab::Extractor::Base.should_receive( :write_full ).with( current, @full_path )
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
- should_eql_file( contents, 'spec/data/android/previous.xml' )
88
+ contents.should eql_file( 'spec/data/android/previous.xml' )
72
89
 
73
90
  contents = Vocab::Extractor::Base.previous_file( @path, '0533bcd9a304cd6e74d6a56959dbcabd57b2f1b9' )
74
- should_eql_file( contents, 'spec/data/android/current.xml' )
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
- should_eql_file( contents, 'spec/data/android/previous.xml' )
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
- should_eql_file( contents, 'spec/data/android/previous.xml' )
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 "previous" do
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.extract_previous( @locales_root )
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.extract_previous( @locales_root )
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 "current" do
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.extract_current( @locales_root )
72
- expected = { :"en.menu.second" =>"Second menu item",
73
- :"en.models.product.id_36.description" =>"Polarized and lazer resistant",
74
- :"en.marketing.banner" =>"This product is so good",
75
- :"en.models.product.id_36.name" =>"This nested value has changed",
76
- :"en.menu.first" =>"First menu item",
77
- :"en.models.product.id_55.description" =>"A new nested description",
78
- :"en.models.product.id_125.description"=>"Green with megawatts",
79
- :"en.dashboard.chart" =>"This value has changed",
80
- :"en.models.product.id_55.name" =>"a new nested name",
81
- :"en.models.product.id_125.name" =>"Lazer",
82
- :"en.dashboard.details" =>"This key/value has been added",
83
- :"en.not_in_es" =>"This key not in spanish" }
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( :extract_current ).and_return( { :en => { 1 => 5, 3 => 4 } } )
98
- Vocab::Extractor::Rails.should_receive( :extract_previous ).and_return( { :en => { 1 => 2 } } )
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
 
@@ -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
- it "merges updated android translations" do
54
- @merged['pd_app_name'].should eql( 'el Panel para padres bien' )
55
- end
51
+ context "strings" do
56
52
 
57
- it "integrates new android translations" do
58
- @merged['cancel'].should eql( 'Cancelar' )
59
- end
53
+ before( :each ) do
54
+ @merged = Vocab::Translator::Android.hash_from_xml( @file )
55
+ end
60
56
 
61
- it "properly encodes html entities" do
62
- @merged['delete'].should eql( "La función Child Lock" )
63
- end
57
+ it "merges updated android translations" do
58
+ @merged['pd_app_name'].should eql( 'el Panel para padres bien' )
59
+ end
64
60
 
65
- it "ignores key accidentally introduced by the translators into android translations" do
66
- @merged['translator_cruft'].should be( nil )
67
- end
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
- it 'does not include keys where there is no translation' do
74
- @merged['not_in_es'].should be( nil )
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 'english_keys' do
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.english_keys.should =~ keys
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 'current_for_locale' do
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.current_for_locale( "#{@merge_dir}/values-es/strings.xml" ).should == expected
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 'updates' do
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
- merger.updates_for_locale( "#{@merge_dir}/values-es/strings.xml" ).should == expected
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
@@ -6,7 +6,6 @@ describe "Vocab::Extractor::Base" do
6
6
 
7
7
  before( :each ) do
8
8
  @merger = Vocab::Merger::Base.new
9
- @merger.should_receive( :update_settings )
10
9
  end
11
10
 
12
11
  it 'merges a list of files' do
@@ -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
- def should_eql_file( actual, path )
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
+
@@ -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 'english_keys' do
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.english_keys( locales_dir ).should =~ expected
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&#xF3;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&#xF3;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