vocab 0.0.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.
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/README.md +58 -0
- data/Rakefile +13 -0
- data/bin/vocab +11 -0
- data/lib/vocab/application.rb +58 -0
- data/lib/vocab/extractor/android.rb +56 -0
- data/lib/vocab/extractor/base.rb +92 -0
- data/lib/vocab/extractor/rails.rb +81 -0
- data/lib/vocab/extractor.rb +7 -0
- data/lib/vocab/merger/android.rb +59 -0
- data/lib/vocab/merger/base.rb +21 -0
- data/lib/vocab/merger/rails.rb +105 -0
- data/lib/vocab/merger.rb +7 -0
- data/lib/vocab/settings.rb +35 -0
- data/lib/vocab/translator/android.rb +43 -0
- data/lib/vocab/translator/base.rb +12 -0
- data/lib/vocab/translator/rails.rb +67 -0
- data/lib/vocab/translator.rb +7 -0
- data/lib/vocab/ui.rb +19 -0
- data/lib/vocab/validator/android.rb +23 -0
- data/lib/vocab/validator/base.rb +40 -0
- data/lib/vocab/validator/rails.rb +31 -0
- data/lib/vocab/validator.rb +7 -0
- data/lib/vocab/version.rb +3 -0
- data/lib/vocab.rb +36 -0
- data/spec/application_spec.rb +20 -0
- data/spec/data/android/current.xml +8 -0
- data/spec/data/android/locales/values/strings.xml +10 -0
- data/spec/data/android/locales/values-es/strings.xml +6 -0
- data/spec/data/android/locales/values-large-hdpi/dimens.xml +1 -0
- data/spec/data/android/locales/values-large-hdpi/styles.xml +1 -0
- data/spec/data/android/previous.xml +6 -0
- data/spec/data/android/translations/values-es/es-string-file.xml +7 -0
- data/spec/data/android/write.xml +6 -0
- data/spec/data/rails/locales/en.yml +10 -0
- data/spec/data/rails/locales/es.yml +6 -0
- data/spec/data/rails/locales/models/product/en.yml +13 -0
- data/spec/data/rails/locales/models/product/es.yml +13 -0
- data/spec/data/rails/translations/cn.yml +21 -0
- data/spec/data/rails/translations/es.yml +12 -0
- data/spec/extractor/android_spec.rb +95 -0
- data/spec/extractor/base_spec.rb +134 -0
- data/spec/extractor/rails_spec.rb +116 -0
- data/spec/merger/android_spec.rb +138 -0
- data/spec/merger/base_spec.rb +24 -0
- data/spec/merger/rails_spec.rb +183 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/matchers.rb +13 -0
- data/spec/support/shared.rb +6 -0
- data/spec/tmp/.gitkeep +0 -0
- data/spec/translator/android_spec.rb +24 -0
- data/spec/translator/rails_spec.rb +155 -0
- data/spec/ui_spec.rb +15 -0
- data/spec/validator/android_spec.rb +54 -0
- data/spec/validator/base_spec.rb +5 -0
- data/spec/validator/rails_spec.rb +83 -0
- data/spec/vocab_spec.rb +13 -0
- data/vocab.gemspec +25 -0
- metadata +171 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# Warning: this object has some sharp edges because it is an unusual use of the i18n gem
|
2
|
+
# For example:
|
3
|
+
# - we are calling private methods
|
4
|
+
# - instances share the I18n.load_path, which could lead to unexpected behavior
|
5
|
+
|
6
|
+
module Vocab
|
7
|
+
module Translator
|
8
|
+
class Rails < Base
|
9
|
+
|
10
|
+
attr_accessor :locale
|
11
|
+
|
12
|
+
def initialize( locale = :en )
|
13
|
+
@backend = I18n::Backend::Simple.new
|
14
|
+
@locale = locale
|
15
|
+
end
|
16
|
+
|
17
|
+
def load_dir( dir )
|
18
|
+
I18n.load_path = Dir.glob( "#{dir}/**/*.{yml,rb}" )
|
19
|
+
load_translations
|
20
|
+
end
|
21
|
+
|
22
|
+
def load_file( file )
|
23
|
+
@locale = File.basename( file ).gsub( /\..*$/, '' ).to_sym
|
24
|
+
I18n.load_path = [ file ]
|
25
|
+
load_translations
|
26
|
+
end
|
27
|
+
|
28
|
+
def write_file( file )
|
29
|
+
yaml = { @locale => self.translations }.to_yaml
|
30
|
+
File.open( file, 'w+' ) { |f| f.write( yaml ) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def translations( options = {} )
|
34
|
+
t = @backend.send(:translations)
|
35
|
+
trans = t[ @locale ]
|
36
|
+
return options[ :prefix ] == true ? { @locale => trans } : trans
|
37
|
+
end
|
38
|
+
|
39
|
+
def flattened_translations( options = {} )
|
40
|
+
return @backend.flatten_translations( @locale, translations( options ), true, false )
|
41
|
+
end
|
42
|
+
|
43
|
+
def store( key, value )
|
44
|
+
keys = I18n.normalize_keys( @locale, key, [], nil)
|
45
|
+
keys.shift # remove locale
|
46
|
+
data = keys.reverse.inject( value ) { |result, _key| { _key => result } }
|
47
|
+
@backend.store_translations( @locale, data )
|
48
|
+
end
|
49
|
+
|
50
|
+
def fetch( key )
|
51
|
+
return flattened_translations[ key.to_sym ]
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.en_equivalent_path( path )
|
55
|
+
return "#{File.dirname( path )}/en.yml"
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def load_translations
|
61
|
+
@backend.reload!
|
62
|
+
@backend.send( :init_translations )
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/vocab/ui.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Vocab
|
2
|
+
module Validator
|
3
|
+
class Android < Base
|
4
|
+
|
5
|
+
def initialize( locales_dir = nil )
|
6
|
+
@locales_dir = locales_dir || 'res'
|
7
|
+
end
|
8
|
+
|
9
|
+
def other_keys( path )
|
10
|
+
return Vocab::Translator::Android.hash_from_xml( path ).keys
|
11
|
+
end
|
12
|
+
|
13
|
+
def english_keys( path = nil )
|
14
|
+
return Vocab::Translator::Android.english_keys( @locales_dir )
|
15
|
+
end
|
16
|
+
|
17
|
+
def files_to_validate
|
18
|
+
return Dir.glob( "#{@locales_dir}/values-*/strings.xml" )
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Vocab
|
2
|
+
module Validator
|
3
|
+
class Base
|
4
|
+
|
5
|
+
def validate
|
6
|
+
files = files_to_validate
|
7
|
+
Vocab.ui.say( "#{files.size} file(s) to validate in #{@locales_dir}" )
|
8
|
+
files.each do |path|
|
9
|
+
validation = validate_file( path )
|
10
|
+
print( path, validation )
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def print( path, validation )
|
15
|
+
Vocab.ui.say( "Validating: #{path}" )
|
16
|
+
|
17
|
+
unless validation[ :missing ].empty?
|
18
|
+
Vocab.ui.say( " Missing keys:" )
|
19
|
+
validation[ :missing ].each { |missing| Vocab.ui.say( " - #{missing}" ) }
|
20
|
+
end
|
21
|
+
|
22
|
+
unless validation[ :extra ].empty?
|
23
|
+
Vocab.ui.say( " Extra keys:" )
|
24
|
+
validation[ :extra ].each { |extra| Vocab.ui.say( " + #{extra}" ) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_file( path )
|
29
|
+
other = other_keys( path )
|
30
|
+
english = english_keys( path )
|
31
|
+
|
32
|
+
result = {}
|
33
|
+
result[ :missing ] = ( english - other ).sort
|
34
|
+
result[ :extra ] = ( other - english ).sort
|
35
|
+
return result
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Vocab
|
2
|
+
module Validator
|
3
|
+
class Rails < Base
|
4
|
+
|
5
|
+
def initialize( locales_dir = nil )
|
6
|
+
@locales_dir = locales_dir || 'config/locales'
|
7
|
+
end
|
8
|
+
|
9
|
+
def other_keys( path )
|
10
|
+
return flattened_keys( path )
|
11
|
+
end
|
12
|
+
|
13
|
+
def english_keys( path )
|
14
|
+
return flattened_keys( Vocab::Translator::Rails.en_equivalent_path( path ) )
|
15
|
+
end
|
16
|
+
|
17
|
+
def files_to_validate
|
18
|
+
return Dir.glob( "#{@locales_dir}/**/*.yml" ).reject { |path| File.basename( path ) == 'en.yml' }
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def flattened_keys( path )
|
24
|
+
translator = Vocab::Translator::Rails.new
|
25
|
+
translator.load_file( path )
|
26
|
+
return translator.flattened_translations.keys.collect { |key| key.to_s }
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/vocab.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'i18n'
|
3
|
+
require 'pathname'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
require 'vocab/application'
|
7
|
+
require 'vocab/extractor'
|
8
|
+
require 'vocab/translator'
|
9
|
+
require 'vocab/merger'
|
10
|
+
require 'vocab/settings'
|
11
|
+
require 'vocab/ui'
|
12
|
+
require 'vocab/validator'
|
13
|
+
require 'vocab/version'
|
14
|
+
|
15
|
+
I18n::Backend::Simple.send( :include, I18n::Backend::Flatten )
|
16
|
+
|
17
|
+
module Vocab
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def settings
|
21
|
+
@settings ||= Settings.new( root )
|
22
|
+
end
|
23
|
+
|
24
|
+
def ui
|
25
|
+
@ui ||= UI.new
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns root directory where .vocab is located
|
29
|
+
# TODO: make this work in subdirectory under .vocab
|
30
|
+
def root
|
31
|
+
return File.expand_path( Dir.pwd )
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "init" do
|
4
|
+
|
5
|
+
before( :each ) do
|
6
|
+
@tmpdir = File.join( vocab_root, "spec", "tmp" )
|
7
|
+
FileUtils.rm_rf( Dir.glob( "#{@tmpdir}/*" ) )
|
8
|
+
Dir.chdir( @tmpdir )
|
9
|
+
end
|
10
|
+
|
11
|
+
it "creates a .vocab file if one doesn't exist" do
|
12
|
+
Vocab.ui.should_receive( :say ).with( "Writing new .vocab file. Check this file into your project repo" )
|
13
|
+
Vocab::Settings.create
|
14
|
+
path = "#{@tmpdir}/.vocab"
|
15
|
+
File.exists?( path ).should be_true
|
16
|
+
YAML.load_file( path ).should == { "last_translation" => `git rev-parse HEAD`.strip }
|
17
|
+
`git rm -f #{path}`
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<resources>
|
3
|
+
<string name="app_name">Kid Mode</string>
|
4
|
+
<string name="pd_app_name">Parent Dashboard</string>
|
5
|
+
<string name="app_current">current</string>
|
6
|
+
<string name="cancel">Cancel</string>
|
7
|
+
<string name="delete">Delete</string>
|
8
|
+
</resources>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<resources>
|
3
|
+
<string name="app_name">Kid Mode</string>
|
4
|
+
<string name="pd_app_name">Parent Dashboard</string>
|
5
|
+
<!-- This is a comment -->
|
6
|
+
<string name="app_current">current</string>
|
7
|
+
<string name="cancel">Cancel</string>
|
8
|
+
<string name="delete">Delete</string>
|
9
|
+
<string name="not_in_es">This key not in spanish</string>
|
10
|
+
</resources>
|
@@ -0,0 +1 @@
|
|
1
|
+
This is just a decoy
|
@@ -0,0 +1 @@
|
|
1
|
+
This is just a decoy
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<resources>
|
3
|
+
<string name="cancel">Cancelar</string>
|
4
|
+
<string name="delete">La función Child Lock</string>
|
5
|
+
<string name="pd_app_name">el Panel para padres bien</string>
|
6
|
+
<string name="translator_cruft">Malo</string>
|
7
|
+
</resources>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
en:
|
3
|
+
models:
|
4
|
+
product:
|
5
|
+
id_125:
|
6
|
+
description: Green with megawatts
|
7
|
+
name: Lazer
|
8
|
+
id_36:
|
9
|
+
description: Polarized and lazer resistant
|
10
|
+
name: This nested value has changed
|
11
|
+
id_55:
|
12
|
+
description: A new nested description
|
13
|
+
name: a new nested name
|
@@ -0,0 +1,21 @@
|
|
1
|
+
cn:
|
2
|
+
marketing:
|
3
|
+
banner: 這改變了營銷信息
|
4
|
+
dashboard:
|
5
|
+
chart: 此值已更改
|
6
|
+
details: 此鍵 /值已添加
|
7
|
+
menu:
|
8
|
+
first: 第一個菜單項
|
9
|
+
second: 第二個菜單項
|
10
|
+
models:
|
11
|
+
product:
|
12
|
+
id_125:
|
13
|
+
description: 綠色與兆瓦
|
14
|
+
name: 休閒
|
15
|
+
id_36:
|
16
|
+
description: 極化和激光耐
|
17
|
+
name: 此嵌套值已更改
|
18
|
+
id_55:
|
19
|
+
description: 一個新的嵌套描述
|
20
|
+
name: 一個新的嵌套的名稱
|
21
|
+
translator_cruft: 這是不小心添加了一個翻譯
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Vocab::Extractor::Android" do
|
4
|
+
|
5
|
+
before( :each ) do
|
6
|
+
@locale = "#{vocab_root}/spec/data/android/locales/values/strings.xml"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'extract_current' do
|
10
|
+
|
11
|
+
it "extracts hash of current string translations" do
|
12
|
+
actual = Vocab::Extractor::Android.extract_current( @locale )
|
13
|
+
actual.should eql( { "app_name" =>"Kid Mode",
|
14
|
+
"delete" =>"Delete",
|
15
|
+
"cancel" =>"Cancel",
|
16
|
+
"app_current"=>"current",
|
17
|
+
"pd_app_name"=>"Parent Dashboard",
|
18
|
+
"not_in_es" =>"This key not in spanish",} )
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'extract_previous' do
|
24
|
+
|
25
|
+
before( :each ) do
|
26
|
+
Dir.chdir( vocab_root )
|
27
|
+
end
|
28
|
+
|
29
|
+
before( :each ) do
|
30
|
+
@sha = '2302e5acb50a9b56d113c46805de5ae0c12d28c0'
|
31
|
+
Vocab.settings.stub!( :last_translation ).and_return( @sha )
|
32
|
+
end
|
33
|
+
|
34
|
+
it "extracts hash of previous string translations" do
|
35
|
+
actual = Vocab::Extractor::Android.extract_previous( @locale )
|
36
|
+
actual.should eql( { 'app_name' => 'Kid Mode',
|
37
|
+
'pd_app_name' => 'Parent Dashboard',
|
38
|
+
'app_current' => 'current' } )
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'write_full' do
|
44
|
+
|
45
|
+
it 'writes the full translation to the correct xml file' do
|
46
|
+
hash = { 'foo' => 'bar' }
|
47
|
+
Vocab::Translator::Android.should_receive( :write ).
|
48
|
+
with( hash, "#{vocab_root}/strings.full.xml" )
|
49
|
+
Vocab::Extractor::Android.write_full( hash )
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'write_diff' do
|
55
|
+
|
56
|
+
it 'writes the diff translation to the correct xml file' do
|
57
|
+
hash = { 'foo' => 'bar' }
|
58
|
+
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ó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 )
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'examples' do
|
81
|
+
|
82
|
+
it 'returns file names for completed translations' do
|
83
|
+
dir = "#{vocab_root}/spec/data/android/locales"
|
84
|
+
actual = Vocab::Extractor::Android.examples( dir )
|
85
|
+
actual.should =~ [ "tmp/translations/values-es" ]
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'uses the conventional android locales directory by default' do
|
89
|
+
Vocab::Translator::Android.should_receive( :locales ).with( "#{vocab_root}/res/values" ).and_return( [] )
|
90
|
+
Vocab::Extractor::Android.examples
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Vocab::Extractor::Base" do
|
4
|
+
|
5
|
+
describe "diff" do
|
6
|
+
|
7
|
+
it "finds the new keys in the current hash" do
|
8
|
+
@current = { 1 => 2, 3 => 4 }
|
9
|
+
@previous = { 1 => 2 }
|
10
|
+
diff = Vocab::Extractor::Base.diff( @previous, @current )
|
11
|
+
diff.should == { 3 => 4 }
|
12
|
+
end
|
13
|
+
|
14
|
+
it "finds the updated keys in the current hash" do
|
15
|
+
@current = { 1 => 10 }
|
16
|
+
@previous = { 1 => 2 }
|
17
|
+
diff = Vocab::Extractor::Base.diff( @previous, @current )
|
18
|
+
diff.should == { 1 => 10 }
|
19
|
+
end
|
20
|
+
|
21
|
+
it "ignores updated keys that begin with 'debug_'" do
|
22
|
+
@current = { 'debug_foo' => 'bar' }
|
23
|
+
@previous = {}
|
24
|
+
diff = Vocab::Extractor::Base.diff( @previous, @current )
|
25
|
+
diff.should == {}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "handles the hash format of the translations" do
|
29
|
+
@current = { :"en.marketing.banner"=>"This product is so good",
|
30
|
+
:"en.models.product.id_125.name"=>"This has been updated",
|
31
|
+
:"en.models.product.id_126.name"=>"This is new"}
|
32
|
+
@previous = { :"en.marketing.banner"=>"This product is so good",
|
33
|
+
:"en.models.product.id_125.name"=>"Lazer"}
|
34
|
+
diff = Vocab::Extractor::Base.diff( @previous, @current )
|
35
|
+
diff.should == { :"en.models.product.id_125.name"=>"This has been updated",
|
36
|
+
:"en.models.product.id_126.name"=>"This is new"}
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "extract" do
|
42
|
+
|
43
|
+
before( :each ) do
|
44
|
+
@diff_path = "#{vocab_root}/spec/tmp/en.yml"
|
45
|
+
@full_path = "#{vocab_root}/spec/tmp/en.yml"
|
46
|
+
File.delete( @diff_path ) if File.exists?( @diff_path )
|
47
|
+
end
|
48
|
+
|
49
|
+
it "extracts the strings that need to be translated into a yml file" do
|
50
|
+
current = { 1 => 5, 3 => 4 }
|
51
|
+
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 )
|
56
|
+
Vocab::Extractor::Base.should_receive( :mkdir_examples )
|
57
|
+
Vocab::Extractor::Base.extract( @diff_path, @full_path )
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "previous_file" do
|
63
|
+
|
64
|
+
before( :each ) do
|
65
|
+
Dir.chdir( vocab_root )
|
66
|
+
@path = "spec/data/android/locales/strings.xml"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns the contents of a file from a specific git version" do
|
70
|
+
contents = Vocab::Extractor::Base.previous_file( @path, 'a19f7c5c28c1158792a966c0d2153a04490dd35e' )
|
71
|
+
should_eql_file( contents, 'spec/data/android/previous.xml' )
|
72
|
+
|
73
|
+
contents = Vocab::Extractor::Base.previous_file( @path, '0533bcd9a304cd6e74d6a56959dbcabd57b2f1b9' )
|
74
|
+
should_eql_file( contents, 'spec/data/android/current.xml' )
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns the correct contents when a full path is specified" do
|
78
|
+
contents = Vocab::Extractor::Base.previous_file( "#{vocab_root}/#{@path}", 'a19f7c5c28c1158792a966c0d2153a04490dd35e' )
|
79
|
+
should_eql_file( contents, 'spec/data/android/previous.xml' )
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns the contents of a file when in a subdir of the git directory" do
|
83
|
+
Dir.chdir( "spec" )
|
84
|
+
@path = "data/android/locales/strings.xml"
|
85
|
+
contents = Vocab::Extractor::Base.previous_file( @path, 'a19f7c5c28c1158792a966c0d2153a04490dd35e' )
|
86
|
+
should_eql_file( contents, 'spec/data/android/previous.xml' )
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'git_root' do
|
92
|
+
|
93
|
+
it 'returns empty string if already at git root' do
|
94
|
+
Dir.chdir( vocab_root )
|
95
|
+
Vocab::Extractor::Base.git_root.should eql( vocab_root )
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'returns path to git root if in subdir' do
|
99
|
+
Dir.chdir( "#{vocab_root}/spec/data" )
|
100
|
+
Vocab::Extractor::Base.git_root.should eql( vocab_root )
|
101
|
+
Dir.chdir( "#{vocab_root}" )
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'git_relative_path' do
|
107
|
+
|
108
|
+
it 'returns the path to the specified file relative to the git root dir' do
|
109
|
+
Dir.chdir( vocab_root )
|
110
|
+
path = "spec/data/android/locales/values/strings.xml"
|
111
|
+
Vocab::Extractor::Base.git_path( path ).should eql( path )
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'returns the path to the specified file relative to the git root dir while in subdir' do
|
115
|
+
Dir.chdir( "#{vocab_root}/spec/data" )
|
116
|
+
path = "android/locales/values/strings.xml"
|
117
|
+
git_path = "spec/data/android/locales/values/strings.xml"
|
118
|
+
Vocab::Extractor::Base.git_path( path ).should eql( git_path )
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'mkdir_examples' do
|
124
|
+
|
125
|
+
it 'creates example directories for completed translations' do
|
126
|
+
examples = [ 'tmp/translations/values-zh', 'tmp/translations/values-zh-rCN' ]
|
127
|
+
examples.each { |example| FileUtils.should_receive( :mkdir_p ).with( example ) }
|
128
|
+
Vocab::Extractor::Base.should_receive( :examples ).and_return( examples )
|
129
|
+
Vocab::Extractor::Base.mkdir_examples
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|