babelyoda 2.0.7 → 2.1.0

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/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ notification :gntp, :sticky => true, :host => '127.0.0.1', :password => ENV['GNTP_PASS']
2
+
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| ["spec/lib/#{m[1]}_spec.rb"] }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/babelyoda.gemspec CHANGED
@@ -17,7 +17,10 @@ Gem::Specification.new do |s|
17
17
  s.require_paths = ["lib"]
18
18
 
19
19
  # specify any dependencies here; for example:
20
- s.add_development_dependency "rspec", '~> 2.8', '>= 2.8.0'
20
+ s.add_development_dependency "rspec"
21
+ s.add_development_dependency "guard"
22
+ s.add_development_dependency "guard-rspec"
23
+ s.add_development_dependency "ruby_gntp"
21
24
  s.add_runtime_dependency "awesome_print", '~> 1.0', '>= 1.0.2'
22
25
  s.add_runtime_dependency "rake", '~> 0.9', '>= 0.9.2.2'
23
26
  s.add_runtime_dependency "active_support", '~> 3.0', '>= 3.0.0'
@@ -59,9 +59,7 @@ module Babelyoda
59
59
 
60
60
  def ensure_languages!(languages = [])
61
61
  @keys.each_value do |key|
62
- languages.each do |language|
63
- key.values[language] ||= Babelyoda::LocalizationValue.new(language, '')
64
- end
62
+ key.ensure_languages!(languages)
65
63
  end
66
64
  end
67
65
 
@@ -1,3 +1,5 @@
1
+ require_relative 'regexp'
2
+
1
3
  module Babelyoda
2
4
  class LocalizationKey
3
5
  attr_reader :id
@@ -8,14 +10,31 @@ module Babelyoda
8
10
  @id = id
9
11
  @context = context
10
12
  @values = {}
13
+ @plural = plural_id?(id)
14
+ @plural_key = plural? ? extract_plural_key(id) : nil
15
+ @id = depluralize_key(@id) if plural?
11
16
  end
12
17
 
13
18
  def to_s
14
19
  "\"#{@id}\" [#{@values.keys.map{|k| ":#{k.to_s}"}.join(', ')}] // #{@context}"
15
20
  end
16
21
 
22
+ def plural? ; @plural ; end
23
+
17
24
  def <<(localization_value)
18
- @values[localization_value.language.to_sym] = localization_value.dup
25
+ raise "Can't merge a plural value into a non-plural key" if !plural? && localization_value.plural?
26
+ lang = localization_value.language.to_sym
27
+ value = localization_value.dup
28
+ if plural?
29
+ value.pluralize!(@plural_key)
30
+ if @values[lang]
31
+ @values[lang].merge!(value, { :preserve => true })
32
+ else
33
+ @values[lang] = value
34
+ end
35
+ else
36
+ @values[lang] = value
37
+ end
19
38
  self
20
39
  end
21
40
 
@@ -23,7 +42,8 @@ module Babelyoda
23
42
  updated = false
24
43
 
25
44
  context_changed = false
26
- if @context != localization_key.context
45
+ new_context = localization_key.context
46
+ if @context != new_context && new_context != nil && new_context.length > 0
27
47
  @context = localization_key.context
28
48
  updated = context_changed = true
29
49
  end
@@ -56,5 +76,16 @@ module Babelyoda
56
76
  def empty?
57
77
  @values.empty?
58
78
  end
79
+
80
+ def ensure_languages!(languages = [])
81
+ languages.each do |language|
82
+ unless self.values[language]
83
+ self << Babelyoda::LocalizationValue.new(language, '')
84
+ end
85
+ end
86
+ end
87
+
88
+ private
89
+ include Babelyoda::Regexp
59
90
  end
60
91
  end
@@ -1,3 +1,5 @@
1
+ require_relative 'regexp'
2
+
1
3
  module Babelyoda
2
4
  class LocalizationValue
3
5
  attr_accessor :language
@@ -6,21 +8,62 @@ module Babelyoda
6
8
 
7
9
  def initialize(language, text, status = :requires_translation)
8
10
  @language, @text, @status = language.to_sym, text, status.to_sym
11
+ pluralize! if plural_id?(@text)
9
12
  end
10
13
 
14
+ def pluralize!(plural_key = :one)
15
+ return if plural?
16
+ new_text = { :one => nil, :some => nil, :many => nil, :none => nil }
17
+
18
+ if plural_id?(text)
19
+ m = plural_match(text)
20
+ new_text[m[2].to_sym] = depluralize_value(@text)
21
+ else
22
+ new_text[plural_key] = text
23
+ end
24
+
25
+ @text = new_text
26
+ end
27
+
28
+ def plural? ; text.kind_of? Hash ; end
29
+
11
30
  def merge!(other_value, options = {})
12
31
  updated = false
13
32
  options = { preserve: false }.merge!(options)
33
+
14
34
  unless @language.to_sym == other_value.language.to_sym
15
- raise RuntimeError.new("Can't merge values in different languages: #{@language.to_sym} and #{other_value.language.to_sym}")
35
+ raise "Can't merge values in different languages: #{@language.to_sym} and #{other_value.language.to_sym}"
16
36
  end
17
- if (!options[:preserve] || @status.to_sym == :requires_translation)
18
- unless @text == other_value.text
19
- @text = other_value.text
20
- updated = true
37
+
38
+ raise "Can't merge a plural and a non-plural value!" unless plural? == other_value.plural?
39
+
40
+ if plural?
41
+ [:one, :some, :many, :none].each do |plural_type|
42
+ key_updated = merge_plural_type!(plural_type, other_value.text[plural_type], options)
43
+ updated ||= key_updated
44
+ end
45
+ else
46
+ if (!options[:preserve] || @status.to_sym == :requires_translation)
47
+ if @text != other_value.text && !other_value.nil?
48
+ @text = other_value.text
49
+ updated = true
50
+ end
21
51
  end
22
52
  end
23
53
  return updated
24
54
  end
55
+
56
+ private
57
+ include Babelyoda::Regexp
58
+
59
+ def merge_plural_type!(type, other_value, options)
60
+ if (!options[:preserve] || @status.to_sym == :requires_translation)
61
+ if @text[type] != other_value && !other_value.nil?
62
+ @text[type] = other_value
63
+ return true
64
+ end
65
+ end
66
+ return false
67
+ end
25
68
  end
26
69
  end
@@ -0,0 +1,30 @@
1
+ module Babelyoda
2
+ module Regexp
3
+ PLURAL_ID = /([^%]|^)%\[(one|some|many|none|plural)\]([^\s])/
4
+ PLURALIZED_ID = /([^%]|^)%\[(plural)\]([^\s])/
5
+
6
+ def plural_id?(id)
7
+ plural_match(id) != nil
8
+ end
9
+
10
+ def plural_match(id)
11
+ id.match(PLURAL_ID)
12
+ end
13
+
14
+ def depluralize_value(id)
15
+ id.gsub(PLURAL_ID, '\1%\3')
16
+ end
17
+
18
+ def depluralize_key(id)
19
+ id.gsub(PLURAL_ID, '\1%[plural]\3')
20
+ end
21
+
22
+ def pluralize_key(id, plural_key)
23
+ id.gsub(PLURALIZED_ID, "\\1%[#{plural_key}]\\3")
24
+ end
25
+
26
+ def extract_plural_key(id)
27
+ id.match(PLURAL_ID)[2].to_sym
28
+ end
29
+ end
30
+ end
@@ -29,7 +29,7 @@ module Babelyoda
29
29
  def self.load
30
30
  trace_spec = @spec.nil? && ::Rake.application.options.trace
31
31
  @spec ||= load_from_file(filename = FILENAME)
32
- @spec.dump if trace_spec && @spec
32
+ @spec.dump if trace_spec && @spec
33
33
  return @spec
34
34
  end
35
35
 
@@ -17,7 +17,11 @@ module Babelyoda
17
17
  end
18
18
 
19
19
  def dump
20
- ap self, :indent => -2
20
+ unless ::Rake.application.options.trace
21
+ ap self, :indent => -2
22
+ else
23
+ p self
24
+ end
21
25
  end
22
26
 
23
27
  module ClassMethods
@@ -6,6 +6,31 @@ require_relative 'strings_lexer'
6
6
  require_relative 'strings_parser'
7
7
 
8
8
  module Babelyoda
9
+ class Keyset
10
+ def to_strings(io, language)
11
+ keys.each_value do |key|
12
+ key.to_strings(io, language)
13
+ end
14
+ end
15
+ end
16
+
17
+ class LocalizationKey
18
+ def to_strings(io, language)
19
+ return if self.values[language].nil?
20
+ io << "/* #{self.context} */\n" if self.context
21
+ if plural?
22
+ values[language].text.keys.each do |plural_key|
23
+ if values[language].text[plural_key] != nil && values[language].text[plural_key].length > 0
24
+ io << "\"#{pluralize_key(id, plural_key)}\" = \"#{values[language].text[plural_key]}\";\n"
25
+ end
26
+ end
27
+ else
28
+ io << "\"#{id}\" = \"#{values[language].text}\";\n"
29
+ end
30
+ io << "\n"
31
+ end
32
+ end
33
+
9
34
  class Strings < Keyset
10
35
  attr_reader :filename
11
36
  attr_reader :language
@@ -36,12 +61,7 @@ module Babelyoda
36
61
  def save!
37
62
  FileUtils.mkdir_p(File.dirname(filename))
38
63
  File.open(filename, "wb") do |f|
39
- keys.each_pair do |id, key|
40
- next unless key.values[language]
41
- f << "/* #{key.context} */\n" if key.context
42
- f << "\"#{id}\" = \"#{key.values[language].text}\";\n"
43
- f << "\n"
44
- end
64
+ to_strings(f, language)
45
65
  end
46
66
  end
47
67
 
@@ -5,19 +5,15 @@ require 'stringio'
5
5
 
6
6
  require_relative 'logger'
7
7
  require_relative 'specification_loader'
8
+ require_relative 'localization_key'
9
+ require_relative 'localization_value'
8
10
 
9
11
  module Babelyoda
10
12
  class Keyset
11
13
  def to_xml(xml, language = nil)
12
14
  xml.keyset(:id => name) do
13
15
  keys.each_value do |key|
14
- xml.key(:id => key.id, :is_plural => 'False') do
15
- xml.context(key.context)
16
- key.values.each_value do |value|
17
- next if language && (value.language.to_s != language.to_s)
18
- xml.value(value.text, :language => value.language, :status => value.status)
19
- end
20
- end
16
+ key.to_xml(xml, language)
21
17
  end
22
18
  end
23
19
  end
@@ -42,14 +38,67 @@ module Babelyoda
42
38
  end
43
39
  result
44
40
  end
41
+
42
+ def to_xml(xml, language = nil)
43
+ xml.key(:id => self.id, :is_plural => (plural? ? 'True' : 'False')) do |key|
44
+ xml << "<context>#{self.context}</context>"
45
+ self.values.each_value do |value|
46
+ next if language && (value.language.to_s != language.to_s)
47
+ value.to_xml(xml)
48
+ end
49
+ end
50
+ end
45
51
  end
46
52
 
47
53
  class LocalizationValue
48
54
  def self.parse_xml(node)
49
- if node.text.length > 0
55
+ if node.css('plural').first
56
+ plural = node.css('plural').first
57
+
58
+ plural_key = plural.css('one').first
59
+ value_one = self.new(node[:language], plural_key.text, node[:status])
60
+ value_one.pluralize!(:one)
61
+
62
+ plural_key = plural.css('some').first
63
+ value_some = self.new(node[:language], plural_key.text, node[:status])
64
+ value_some.pluralize!(:some)
65
+
66
+ plural_key = plural.css('many').first
67
+ value_many = self.new(node[:language], plural_key.text, node[:status])
68
+ value_many.pluralize!(:many)
69
+
70
+ plural_key = plural.css('none').first
71
+ value_none = self.new(node[:language], plural_key.text, node[:status])
72
+ value_none.pluralize!(:none)
73
+
74
+ value_one.merge!(value_some)
75
+ value_one.merge!(value_many)
76
+ value_one.merge!(value_none)
77
+
78
+ value_one.text.keys.each do |k|
79
+ value_one.text[k] = nil if value_one.text[k] == ''
80
+ end
81
+
82
+ value_one
83
+ elsif node.text.length > 0
50
84
  self.new(node[:language], node.text, node[:status])
51
85
  end
52
86
  end
87
+
88
+ def to_xml(xml)
89
+ unless plural?
90
+ xml.value(self.text, :language => self.language, :status => self.status)
91
+ else
92
+ xml.value(:language => self.language, :status => self.status) do |value|
93
+ value.plural do |plural|
94
+ plural.one text[:one] || ''
95
+ plural.some text[:some] || ''
96
+ plural.many text[:many] || ''
97
+ plural.none text[:none] || ''
98
+ end
99
+ end
100
+ end
101
+ end
53
102
  end
54
103
 
55
104
  class Tanker
@@ -124,13 +173,14 @@ module Babelyoda
124
173
  end
125
174
 
126
175
  def project_xml(&block)
127
- xml = Builder::XmlMarkup.new
128
- xml.instruct!(:xml, :encoding => "UTF-8")
129
- xml.tanker do
130
- xml.project(:id => project_id) do
131
- yield xml
176
+ xml = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
177
+ xml.tanker do
178
+ xml.project(:id => project_id) do
179
+ yield xml
180
+ end
132
181
  end
133
182
  end
183
+ xml.to_xml(:indent => 2)
134
184
  end
135
185
 
136
186
  def multipart_data(payload = {}, boundary = MULTIPART_BOUNDARY)
@@ -1,3 +1,3 @@
1
1
  module Babelyoda
2
- VERSION = "2.0.7"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -0,0 +1,43 @@
1
+ require 'babelyoda/strings_lexer'
2
+ require 'babelyoda/strings_parser'
3
+ require 'babelyoda/keyset'
4
+
5
+ describe "keyset" do
6
+ it "can be created" do
7
+ keyset = Babelyoda::Keyset.new('Combined')
8
+ keyset.name.should == 'Combined'
9
+ keyset.keys.size.should == 0
10
+ end
11
+
12
+ it "should correctly merge plural keys" do
13
+ lexer = Babelyoda::StringsLexer.new
14
+ parser = Babelyoda::StringsParser.new(lexer, :en)
15
+ str = <<-EOF
16
+ /* Some comment */
17
+ "Some plural %[one]u key" = "Some translation for one %u";
18
+ /* Some comment */
19
+ "Some plural %[some]u key" = "Some translation for some %u";
20
+ /* Some comment */
21
+ "Some plural %[many]u key" = "Some translation for many %u";
22
+ /* Some comment */
23
+ "Some plural %[none]u key" = "Some translation for none %u";
24
+ EOF
25
+ keyset = Babelyoda::Keyset.new('Combined')
26
+ parser.parse(str) do |record|
27
+ keyset.merge_key!(record)
28
+ end
29
+ keyset.keys.size.should == 1
30
+ key = keyset.keys['Some plural %[plural]u key']
31
+ key.should_not == nil
32
+ key.id.should == 'Some plural %[plural]u key'
33
+ key.values.size.should == 1
34
+ value = key.values[:en]
35
+ value.should_not == nil
36
+ value.plural?.should == true
37
+ text = value.text
38
+ text[:one].should == 'Some translation for one %u'
39
+ text[:some].should == 'Some translation for some %u'
40
+ text[:many].should == 'Some translation for many %u'
41
+ text[:none].should == 'Some translation for none %u'
42
+ end
43
+ end
@@ -0,0 +1,152 @@
1
+ require 'babelyoda/localization_key'
2
+ require 'babelyoda/localization_value'
3
+
4
+ describe "basic localization key" do
5
+ it "can be created" do
6
+ key = Babelyoda::LocalizationKey.new("Hello world!", "Some translator comment")
7
+ key.values.size.should == 0
8
+ end
9
+
10
+ it "should not be marked as plural" do
11
+ key = Babelyoda::LocalizationKey.new("Hello world!", "Some translator comment")
12
+ key.plural?.should == false
13
+ end
14
+
15
+ it "ensures the set of languages is present" do
16
+ key = Babelyoda::LocalizationKey.new("Hello world!", "Some translator comment")
17
+ key.ensure_languages!([:en, :ru])
18
+ [:en, :ru].each do |lang|
19
+ value = key.values[lang]
20
+ value.should_not == nil
21
+ value.plural?.should == false
22
+ end
23
+ [:tr, :uk].each do |lang|
24
+ value = key.values[lang]
25
+ value.should == nil
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ describe "plural localization key" do
32
+ it "can be created with a plural id of [one]" do
33
+ key = Babelyoda::LocalizationKey.new("%[one]d organization nearby", "The number of organizations")
34
+ key.plural?.should == true
35
+ key.id.should == "%[plural]d organization nearby"
36
+ end
37
+
38
+ it "can be created with a plural id of [some]" do
39
+ key = Babelyoda::LocalizationKey.new("%[some]d organization nearby", "The number of organizations")
40
+ key.plural?.should == true
41
+ key.id.should == "%[plural]d organization nearby"
42
+ end
43
+
44
+ it "can be created with a plural id of [many]" do
45
+ key = Babelyoda::LocalizationKey.new("%[many]d organization nearby", "The number of organizations")
46
+ key.plural?.should == true
47
+ key.id.should == "%[plural]d organization nearby"
48
+ end
49
+
50
+ it "can be created with a plural id of [none]" do
51
+ key = Babelyoda::LocalizationKey.new("%[none]d organization nearby", "The number of organizations")
52
+ key.plural?.should == true
53
+ key.id.should == "%[plural]d organization nearby"
54
+ end
55
+
56
+ it "%% should be ignored and the key be singular" do
57
+ key = Babelyoda::LocalizationKey.new("%%[none]d organization nearby", "The number of organizations")
58
+ key.plural?.should == false
59
+ key.id.should == "%%[none]d organization nearby"
60
+ end
61
+
62
+ context "after a pluralized key has been created" do
63
+
64
+ before(:each) do
65
+ @key = Babelyoda::LocalizationKey.new("%[one]d organization nearby", "The number of organizations")
66
+ end
67
+
68
+ it "should pluralize given values" do
69
+ value = Babelyoda::LocalizationValue.new(:en, "%[one]d organization nearby")
70
+ @key << value
71
+ @key.values.size.should == 1
72
+ value = @key.values[:en]
73
+ value.plural?.should == true
74
+ value.text.kind_of?(Hash).should == true
75
+ end
76
+
77
+ it "should merge plural values for different plurals of the same key" do
78
+ value1 = Babelyoda::LocalizationValue.new(:en, "%[one]d organization nearby")
79
+ value2 = Babelyoda::LocalizationValue.new(:en, "%[some]d organization nearby")
80
+ @key << value1
81
+ @key << value2
82
+ @key.values.size.should == 1
83
+ value = @key.values[:en]
84
+ value.plural?.should == true
85
+ value.text[:one].should == '%d organization nearby'
86
+ value.text[:some].should == '%d organization nearby'
87
+ value.text[:many].should == nil
88
+ value.text[:none].should == nil
89
+ end
90
+
91
+ end
92
+
93
+ it "should correctly merge non-plural value into the correct plural key :one" do
94
+ key = Babelyoda::LocalizationKey.new("%[one]d organization nearby", "The number of organizations")
95
+ value = Babelyoda::LocalizationValue.new(:en, "%d organization nearby")
96
+ key << value
97
+ value = key.values[:en]
98
+ value.text[:one].should == '%d organization nearby'
99
+ end
100
+
101
+ it "should correctly merge non-plural value into the correct plural key :some" do
102
+ key = Babelyoda::LocalizationKey.new("%[some]d organization nearby", "The number of organizations")
103
+ value = Babelyoda::LocalizationValue.new(:en, "%d organization nearby")
104
+ key << value
105
+ value = key.values[:en]
106
+ value.text[:some].should == '%d organization nearby'
107
+ end
108
+
109
+ it "should correctly depluralize the key with the plural key in the middle of the key" do
110
+ key = Babelyoda::LocalizationKey.new("Some plural %[none]u key", "The number of organizations")
111
+ key.id.should == 'Some plural %[plural]u key'
112
+ key.plural?.should == true
113
+ end
114
+
115
+ it "should correctly depluralize the key with the plural key at the beginning of the key" do
116
+ key = Babelyoda::LocalizationKey.new("%[none]u key", "The number of organizations")
117
+ key.id.should == '%[plural]u key'
118
+ key.plural?.should == true
119
+ end
120
+
121
+ it "should correctly depluralize the key with the plural key at the end of the key" do
122
+ key = Babelyoda::LocalizationKey.new("the key is %[none]u", "The number of organizations")
123
+ key.id.should == 'the key is %[plural]u'
124
+ key.plural?.should == true
125
+ end
126
+
127
+ it "should not override a non-empty context with an empty context on merge" do
128
+ key1 = Babelyoda::LocalizationKey.new("the key is %[none]u", "Non empty context")
129
+ key2 = Babelyoda::LocalizationKey.new("the key is %[none]u", "")
130
+ key1.merge!(key2)
131
+ key1.context.should == "Non empty context"
132
+ end
133
+
134
+ it "ensures the set of languages is present" do
135
+ key = Babelyoda::LocalizationKey.new("the key is %[none]u", "Non empty context")
136
+ key.ensure_languages!([:en, :ru])
137
+ [:en, :ru].each do |lang|
138
+ value = key.values[lang]
139
+ value.should_not == nil
140
+ value.plural?.should == true
141
+ [:one, :some, :many].each do |plural_key|
142
+ value.text[plural_key].should == nil
143
+ end
144
+ value.text[:none].should == ''
145
+ end
146
+ [:tr, :uk].each do |lang|
147
+ value = key.values[lang]
148
+ value.should == nil
149
+ end
150
+ end
151
+
152
+ end
@@ -0,0 +1,17 @@
1
+ require 'babelyoda/localization_value'
2
+
3
+ describe "localization value" do
4
+ it "can be created" do
5
+ value = Babelyoda::LocalizationValue.new(:en, "Value 1")
6
+ value.language.should == :en
7
+ value.text.should == "Value 1"
8
+ end
9
+
10
+ it "should merge non-plural values" do
11
+ value1 = Babelyoda::LocalizationValue.new(:en, "Value 1")
12
+ value2 = Babelyoda::LocalizationValue.new(:en, "Value 2")
13
+ value1.merge!(value2)
14
+ value1.language.should == :en
15
+ value1.text.should == "Value 2"
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ require "babelyoda/strings_lexer"
2
+
3
+ describe "strings lexer" do
4
+ it "can be created" do
5
+ lexer = Babelyoda::StringsLexer.new
6
+ end
7
+
8
+ context "basic strings lexer" do
9
+
10
+ before(:each) do
11
+ @lexer = Babelyoda::StringsLexer.new
12
+ end
13
+
14
+ it "can parse tokens" do
15
+ str = <<-EOF
16
+ /* Some comment */
17
+ "Some key" = "Some translation";
18
+ EOF
19
+ result = []
20
+ @lexer.lex(str) do |token, value|
21
+ result << { :token => token, :value => value }
22
+ end
23
+ result.size.should == 5
24
+ result[0][:token].should == :multiline_comment
25
+ result[0][:value].should == "/* Some comment */"
26
+ result[1][:token].should == :string
27
+ result[1][:value].should == "\"Some key\""
28
+ result[2][:token].should == :equal_sign
29
+ result[2][:value].should == "="
30
+ result[3][:token].should == :string
31
+ result[3][:value].should == "\"Some translation\""
32
+ result[4][:token].should == :semicolon
33
+ result[4][:value].should == ";"
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,57 @@
1
+ require 'babelyoda/strings_lexer'
2
+ require 'babelyoda/strings_parser'
3
+
4
+ describe "strings parser" do
5
+ before(:each) do
6
+ @lexer = Babelyoda::StringsLexer.new
7
+ end
8
+
9
+ it "can be created" do
10
+ parser = Babelyoda::StringsParser.new(@lexer, :en)
11
+ end
12
+
13
+ context "parsing" do
14
+ before(:each) do
15
+ @parser = Babelyoda::StringsParser.new(@lexer, :en)
16
+ end
17
+
18
+ it "should parse simple keys" do
19
+ str = <<-EOF
20
+ /* Some comment */
21
+ "Some key" = "Some translation";
22
+ EOF
23
+ result = []
24
+ @parser.parse(str) do |record|
25
+ result << record
26
+ end
27
+ result.size.should == 1
28
+ result[0].context.should == "Some comment"
29
+ result[0].id.should == "Some key"
30
+ result[0].values.size.should == 1
31
+ result[0].plural?.should == false
32
+ result[0].values[:en].language.should == :en
33
+ result[0].values[:en].status.should == :requires_translation
34
+ result[0].values[:en].text.should == "Some translation"
35
+ end
36
+
37
+ it "should parse plural keys" do
38
+ str = <<-EOF
39
+ // Some comment
40
+ "%[one]d organizations" = "%[one]d organizations";
41
+ EOF
42
+ result = []
43
+ @parser.parse(str) do |record|
44
+ result << record
45
+ end
46
+ result.size.should == 1
47
+ result[0].context.should == "Some comment"
48
+ result[0].id.should == "%[plural]d organizations"
49
+ result[0].values.size.should == 1
50
+ result[0].plural?.should == true
51
+ result[0].values[:en].language.should == :en
52
+ result[0].values[:en].status.should == :requires_translation
53
+ result[0].values[:en].text[:one].should == "%d organizations"
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,71 @@
1
+ require 'babelyoda/strings'
2
+
3
+ describe "strings-based keyset" do
4
+ it "can be created with a filename and language" do
5
+ strings = Babelyoda::Strings.new('Combined.strings', :en)
6
+ end
7
+
8
+ context "when empty" do
9
+ it "serializes to an IO object" do
10
+ strings = Babelyoda::Strings.new('Combined.strings', :en)
11
+ io = StringIO.new
12
+ strings.to_strings(io, :en)
13
+ io.read.should == ''
14
+ end
15
+ end
16
+
17
+ context "when has only non-plural keys" do
18
+ it "merges keys in" do
19
+ strings = Babelyoda::Strings.new('Combined.strings', :en)
20
+ value = Babelyoda::LocalizationValue.new(:en, 'Some translation')
21
+ key = Babelyoda::LocalizationKey.new('Some key', 'Some comment')
22
+ key << value
23
+ strings.merge_key!(key)
24
+ strings.keys.size.should == 1
25
+ end
26
+
27
+ it "serializes to an IO object" do
28
+ strings = Babelyoda::Strings.new('Combined.strings', :en)
29
+
30
+ value = Babelyoda::LocalizationValue.new(:en, 'Some translation')
31
+ key = Babelyoda::LocalizationKey.new('Some key', 'Some comment')
32
+ key << value
33
+ strings.merge_key!(key)
34
+
35
+ io = StringIO.new
36
+ strings.to_strings(io, :en)
37
+ io.rewind
38
+ io.read.should ==
39
+ <<-EOF
40
+ /* Some comment */
41
+ "Some key" = "Some translation";
42
+
43
+ EOF
44
+ end
45
+ end
46
+
47
+ context "with plural keys" do
48
+ it "serializes to an IO object" do
49
+ strings = Babelyoda::Strings.new('Combined.strings', :en)
50
+
51
+ value_one = Babelyoda::LocalizationValue.new(:en, 'Some translation for %d one')
52
+ value_some = Babelyoda::LocalizationValue.new(:en, 'Some translation for %d some')
53
+ value_some.pluralize!(:some)
54
+ key = Babelyoda::LocalizationKey.new('Some %[one]d plural key', 'Some comment')
55
+ key << value_one
56
+ key << value_some
57
+ strings.merge_key!(key)
58
+
59
+ io = StringIO.new
60
+ strings.to_strings(io, :en)
61
+ io.rewind
62
+ io.read.should ==
63
+ <<-EOF
64
+ /* Some comment */
65
+ "Some %[one]d plural key" = "Some translation for %d one";
66
+ "Some %[some]d plural key" = "Some translation for %d some";
67
+
68
+ EOF
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,164 @@
1
+ require 'babelyoda/tanker'
2
+
3
+ describe "tanker XML serialization" do
4
+ it "should serialize non-plural values" do
5
+ value = Babelyoda::LocalizationValue.new(:en, "Some translation")
6
+
7
+ builder = Nokogiri::XML::Builder.new do |xml|
8
+ value.to_xml(xml)
9
+ end
10
+
11
+ builder.to_xml.should == "<?xml version=\"1.0\"?>\n<value language=\"en\" status=\"requires_translation\">Some translation</value>\n"
12
+ end
13
+
14
+ it "should serialize plural values" do
15
+ value = Babelyoda::LocalizationValue.new(:en, "some plural %u translation")
16
+ value.pluralize!
17
+
18
+ builder = Nokogiri::XML::Builder.new do |xml|
19
+ value.to_xml(xml)
20
+ end
21
+
22
+ builder.to_xml.should == '<?xml version="1.0"?>' + "\n" +
23
+ '<value language="en" status="requires_translation">' + "\n" +
24
+ ' <plural>' + "\n" +
25
+ ' <one>some plural %u translation</one>' + "\n" +
26
+ ' <some></some>' + "\n" +
27
+ ' <many></many>' + "\n" +
28
+ ' <none></none>' + "\n" +
29
+ ' </plural>' + "\n" +
30
+ '</value>' + "\n"
31
+ end
32
+
33
+ it "should serialize non-plural keys" do
34
+ key = Babelyoda::LocalizationKey.new("Some key", "Some context")
35
+ value = Babelyoda::LocalizationValue.new(:en, "Some translation")
36
+ key << value
37
+
38
+ builder = Nokogiri::XML::Builder.new do |xml|
39
+ key.to_xml(xml)
40
+ end
41
+
42
+ builder.to_xml.should == "<?xml version=\"1.0\"?>\n" +
43
+ "<key id=\"Some key\" is_plural=\"False\">\n" +
44
+ " <context>Some context</context>\n" +
45
+ " <value language=\"en\" status=\"requires_translation\">Some translation</value>\n" +
46
+ "</key>\n"
47
+ end
48
+
49
+ it "should serialize plural keys" do
50
+ key = Babelyoda::LocalizationKey.new("Some %[one]d plural key", "Some context")
51
+
52
+ value = Babelyoda::LocalizationValue.new(:en, "Some translation for one")
53
+ value.pluralize!(:one)
54
+ key << value
55
+
56
+ value = Babelyoda::LocalizationValue.new(:en, "Some translation for some")
57
+ value.pluralize!(:some)
58
+ key << value
59
+
60
+ builder = Nokogiri::XML::Builder.new do |xml|
61
+ key.to_xml(xml)
62
+ end
63
+
64
+ builder.to_xml.should ==
65
+ <<-EOF
66
+ <?xml version="1.0"?>
67
+ <key id="Some %[plural]d plural key" is_plural="True">
68
+ <context>Some context</context>
69
+ <value language="en" status="requires_translation">
70
+ <plural>
71
+ <one>Some translation for one</one>
72
+ <some>Some translation for some</some>
73
+ <many></many>
74
+ <none></none>
75
+ </plural>
76
+ </value>
77
+ </key>
78
+ EOF
79
+ end
80
+
81
+ it "should parse non-plural value" do
82
+ doc = Nokogiri::XML.parse(
83
+ <<-EOF
84
+ <?xml version="1.0"?>
85
+ <value language="en" status="requires_translation">Some translation</value>
86
+ EOF
87
+ )
88
+ value = Babelyoda::LocalizationValue.parse_xml(doc.root)
89
+ value.language.should == :en
90
+ value.status.should == :requires_translation
91
+ value.text.should == 'Some translation'
92
+ value.plural?.should == false
93
+ end
94
+
95
+ it "should parse plural value" do
96
+ doc = Nokogiri::XML.parse(
97
+ <<-EOF
98
+ <?xml version="1.0"?>
99
+ <value language="en" status="requires_translation">
100
+ <plural>
101
+ <one>Some translation for one</one>
102
+ <some>Some translation for some</some>
103
+ <many></many>
104
+ <none></none>
105
+ </plural>
106
+ </value>
107
+ EOF
108
+ )
109
+ value = Babelyoda::LocalizationValue.parse_xml(doc.root)
110
+ value.language.should == :en
111
+ value.status.should == :requires_translation
112
+ value.plural?.should == true
113
+ value.text[:one].should == 'Some translation for one'
114
+ value.text[:some].should == 'Some translation for some'
115
+ value.text[:many].should == nil
116
+ value.text[:noen].should == nil
117
+ end
118
+
119
+ it "should parse non-plural key" do
120
+ doc = Nokogiri::XML.parse(
121
+ <<-EOF
122
+ <?xml version="1.0"?>
123
+ <key id="Some key" is_plural="False">
124
+ <value language="en" status="requires_translation">Some translation</value>
125
+ </key>
126
+ EOF
127
+ )
128
+ key = Babelyoda::LocalizationKey.parse_xml(doc.root)
129
+ key.id.should == "Some key"
130
+ key.plural?.should == false
131
+ key.values.size.should == 1
132
+ value = key.values[:en]
133
+ value.should_not == nil
134
+ value.text.should == "Some translation"
135
+ end
136
+
137
+ it "should parse plural key" do
138
+ doc = Nokogiri::XML.parse(
139
+ <<-EOF
140
+ <?xml version="1.0"?>
141
+ <key id="Some %[plural]d key" is_plural="True">
142
+ <value language="en" status="requires_translation">
143
+ <plural>
144
+ <one>Some translation for %d one</one>
145
+ <some>Some translation for %d some</some>
146
+ <many></many>
147
+ <none></none>
148
+ </plural>
149
+ </value>
150
+ </key>
151
+ EOF
152
+ )
153
+ key = Babelyoda::LocalizationKey.parse_xml(doc.root)
154
+ key.id.should == "Some %[plural]d key"
155
+ key.plural?.should == true
156
+ key.values.size.should == 1
157
+ value = key.values[:en]
158
+ value.should_not == nil
159
+ value.text[:one].should == 'Some translation for %d one'
160
+ value.text[:some].should == 'Some translation for %d some'
161
+ value.text[:many].should == nil
162
+ value.text[:none].should == nil
163
+ end
164
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: babelyoda
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,25 +9,55 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-23 00:00:00.000000000Z
12
+ date: 2012-01-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70346691069900 !ruby/object:Gem::Requirement
16
+ requirement: &70220783285460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '2.8'
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70220783285460
25
+ - !ruby/object:Gem::Dependency
26
+ name: guard
27
+ requirement: &70220783285040 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70220783285040
36
+ - !ruby/object:Gem::Dependency
37
+ name: guard-rspec
38
+ requirement: &70220783284600 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70220783284600
47
+ - !ruby/object:Gem::Dependency
48
+ name: ruby_gntp
49
+ requirement: &70220783284180 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
22
52
  - - ! '>='
23
53
  - !ruby/object:Gem::Version
24
- version: 2.8.0
54
+ version: '0'
25
55
  type: :development
26
56
  prerelease: false
27
- version_requirements: *70346691069900
57
+ version_requirements: *70220783284180
28
58
  - !ruby/object:Gem::Dependency
29
59
  name: awesome_print
30
- requirement: &70346691067000 !ruby/object:Gem::Requirement
60
+ requirement: &70220783283640 !ruby/object:Gem::Requirement
31
61
  none: false
32
62
  requirements:
33
63
  - - ~>
@@ -38,10 +68,10 @@ dependencies:
38
68
  version: 1.0.2
39
69
  type: :runtime
40
70
  prerelease: false
41
- version_requirements: *70346691067000
71
+ version_requirements: *70220783283640
42
72
  - !ruby/object:Gem::Dependency
43
73
  name: rake
44
- requirement: &70346691064320 !ruby/object:Gem::Requirement
74
+ requirement: &70220783282840 !ruby/object:Gem::Requirement
45
75
  none: false
46
76
  requirements:
47
77
  - - ~>
@@ -52,10 +82,10 @@ dependencies:
52
82
  version: 0.9.2.2
53
83
  type: :runtime
54
84
  prerelease: false
55
- version_requirements: *70346691064320
85
+ version_requirements: *70220783282840
56
86
  - !ruby/object:Gem::Dependency
57
87
  name: active_support
58
- requirement: &70346691060660 !ruby/object:Gem::Requirement
88
+ requirement: &70220783282100 !ruby/object:Gem::Requirement
59
89
  none: false
60
90
  requirements:
61
91
  - - ~>
@@ -66,10 +96,10 @@ dependencies:
66
96
  version: 3.0.0
67
97
  type: :runtime
68
98
  prerelease: false
69
- version_requirements: *70346691060660
99
+ version_requirements: *70220783282100
70
100
  - !ruby/object:Gem::Dependency
71
101
  name: rchardet19
72
- requirement: &70346691057880 !ruby/object:Gem::Requirement
102
+ requirement: &70220783281360 !ruby/object:Gem::Requirement
73
103
  none: false
74
104
  requirements:
75
105
  - - ~>
@@ -80,10 +110,10 @@ dependencies:
80
110
  version: 1.3.5
81
111
  type: :runtime
82
112
  prerelease: false
83
- version_requirements: *70346691057880
113
+ version_requirements: *70220783281360
84
114
  - !ruby/object:Gem::Dependency
85
115
  name: builder
86
- requirement: &70346691048740 !ruby/object:Gem::Requirement
116
+ requirement: &70220783280620 !ruby/object:Gem::Requirement
87
117
  none: false
88
118
  requirements:
89
119
  - - ~>
@@ -94,10 +124,10 @@ dependencies:
94
124
  version: 3.0.0
95
125
  type: :runtime
96
126
  prerelease: false
97
- version_requirements: *70346691048740
127
+ version_requirements: *70220783280620
98
128
  - !ruby/object:Gem::Dependency
99
129
  name: nokogiri
100
- requirement: &70346691045860 !ruby/object:Gem::Requirement
130
+ requirement: &70220783279860 !ruby/object:Gem::Requirement
101
131
  none: false
102
132
  requirements:
103
133
  - - ~>
@@ -108,10 +138,10 @@ dependencies:
108
138
  version: 1.5.0
109
139
  type: :runtime
110
140
  prerelease: false
111
- version_requirements: *70346691045860
141
+ version_requirements: *70220783279860
112
142
  - !ruby/object:Gem::Dependency
113
143
  name: term-ansicolor
114
- requirement: &70346691044020 !ruby/object:Gem::Requirement
144
+ requirement: &70220783279120 !ruby/object:Gem::Requirement
115
145
  none: false
116
146
  requirements:
117
147
  - - ~>
@@ -122,10 +152,10 @@ dependencies:
122
152
  version: 1.0.7
123
153
  type: :runtime
124
154
  prerelease: false
125
- version_requirements: *70346691044020
155
+ version_requirements: *70220783279120
126
156
  - !ruby/object:Gem::Dependency
127
157
  name: log4r-color
128
- requirement: &70346691024920 !ruby/object:Gem::Requirement
158
+ requirement: &70220783278400 !ruby/object:Gem::Requirement
129
159
  none: false
130
160
  requirements:
131
161
  - - ~>
@@ -133,7 +163,7 @@ dependencies:
133
163
  version: '1.2'
134
164
  type: :runtime
135
165
  prerelease: false
136
- version_requirements: *70346691024920
166
+ version_requirements: *70220783278400
137
167
  description: A simple utility to push/pull l10n resources of an Xcode project to/from
138
168
  the translators
139
169
  email:
@@ -145,6 +175,7 @@ files:
145
175
  - .gitignore
146
176
  - CHANGELOG
147
177
  - Gemfile
178
+ - Guardfile
148
179
  - LICENSE
149
180
  - README.rdoc
150
181
  - Rakefile
@@ -160,6 +191,7 @@ files:
160
191
  - lib/babelyoda/localization_value.rb
161
192
  - lib/babelyoda/logger.rb
162
193
  - lib/babelyoda/rake.rb
194
+ - lib/babelyoda/regexp.rb
163
195
  - lib/babelyoda/specification.rb
164
196
  - lib/babelyoda/specification_loader.rb
165
197
  - lib/babelyoda/strings.rb
@@ -168,6 +200,13 @@ files:
168
200
  - lib/babelyoda/tanker.rb
169
201
  - lib/babelyoda/version.rb
170
202
  - lib/babelyoda/xib.rb
203
+ - spec/lib/babelyoda/keyset_spec.rb
204
+ - spec/lib/babelyoda/localization_key_spec.rb
205
+ - spec/lib/babelyoda/localization_value_spec.rb
206
+ - spec/lib/babelyoda/strings_lexer_spec.rb
207
+ - spec/lib/babelyoda/strings_parser_spec.rb
208
+ - spec/lib/babelyoda/strings_spec.rb
209
+ - spec/lib/babelyoda/tanker_spec.rb
171
210
  - templates/Babelfile.erb
172
211
  homepage: http://github.com/eploko/babelyoda
173
212
  licenses: []
@@ -183,7 +222,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
222
  version: '0'
184
223
  segments:
185
224
  - 0
186
- hash: -1238750056866448662
225
+ hash: -2015034540121504841
187
226
  required_rubygems_version: !ruby/object:Gem::Requirement
188
227
  none: false
189
228
  requirements:
@@ -192,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
231
  version: '0'
193
232
  segments:
194
233
  - 0
195
- hash: -1238750056866448662
234
+ hash: -2015034540121504841
196
235
  requirements: []
197
236
  rubyforge_project: babelyoda
198
237
  rubygems_version: 1.8.10