csv2strings 0.2.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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTA4ZWFmNjA3MzBiZjQ0YzU0MmJhMjk5YmE4MjVhMTA3NTBlNzFhMg==
5
+ data.tar.gz: !binary |-
6
+ MzFmNDRlOGY2ZWQwNzc1MTg1MWU4NGQ4MjBkZjBlYWIzYTY2YTNmYg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NTEyY2M2NmVkN2NiMzcyMzAyOWJkNzg3ODM3MDEwZGU3ZGFlOTM4ZDc5ZjNl
10
+ OGI5YjBkY2U4MTA3ZTMwOTE1NDU5ODNhNjEzNTY5NTJjMTkxY2IwNTY0Njk5
11
+ NjVjOTdiNWIzZmMzODI5Yzg4OWMwM2VhYWRjMmI4OGIzMGNlNGM=
12
+ data.tar.gz: !binary |-
13
+ OTI4YjZjMjIzMWVhZDc2MDI3NDFmYzBlNjE3OWVmYWNmZThkODg0M2EzZWQx
14
+ MGExY2ExMTkwYjExOTkxMzViOTNhYzA1YjQwMjg2NDMzMTQwODUyNWIwZDhj
15
+ NWFlNGVlNmY4YWM5OTk5MDdlMWQwM2I5NTFmY2RlMjI5MmEzM2Y=
@@ -0,0 +1,5 @@
1
+ # This is a sample configuration file
2
+ filenames: ["test/data/test_en.strings", "test/data/test_fr.strings"]
3
+ headers: ["Constants", "English", "French"]
4
+ csv_filename: "testconfig.csv"
5
+ dryrun: true
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ *.csv
2
+ *.strings
3
+ *.lproj
4
+ .rbenv-version
5
+ *~
6
+ *#
7
+ *.gem
8
+ *.sublime-project
9
+ #*#
10
+ .csvconverter
11
+ coverage
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - 1.8.7
6
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in teachmehowtomakearubygem.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,30 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ csv2strings (0.2)
5
+ thor
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ metaclass (0.0.1)
11
+ mocha (0.10.5)
12
+ metaclass (~> 0.0.1)
13
+ multi_json (1.3.6)
14
+ rake (0.9.2.2)
15
+ simplecov (0.6.4)
16
+ multi_json (~> 1.0)
17
+ simplecov-html (~> 0.5.3)
18
+ simplecov-html (0.5.3)
19
+ test-unit (2.4.8)
20
+ thor (0.17.0)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ csv2strings!
27
+ mocha
28
+ rake
29
+ simplecov
30
+ test-unit
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 François Benaiteau
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ [![Build Status](https://secure.travis-ci.org/netbe/CSV-to-iOS-Localizable.strings-converter.png?branch=master)](http://travis-ci.org/netbe/CSV-to-iOS-Localizable.strings-converter)
2
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/netbe/CSV-to-iOS-Localizable.strings-converter)
3
+ # Introduction
4
+ This script converts a csv file of translations into iOS .strings files and vice-versa.
5
+
6
+ # Setup
7
+
8
+ `gem install csvconverter`
9
+
10
+ # Usage
11
+
12
+ * Convert csv to localizable strings files:
13
+
14
+ `csv2strings <csvfilename>`
15
+
16
+ * Convert localizable strings files to csv:
17
+
18
+ `strings2csv <stringsfile1> <stringsfile2>`
19
+
20
+ * Use configuration file
21
+
22
+ You can use a configuration file to hold all your commandline arguments into a file (previous versions `i18n_config.rb`).
23
+ Place `.csvconverter` file (edit if needed) in the folder with your ``xx.lproj`` and call the script from there. See `.csvconverter.sample`
24
+
25
+
26
+ # Todo
27
+
28
+ See GitHub isssues
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << "test"
5
+ t.test_files = FileList['test/**/*_test.rb']
6
+ end
7
+
8
+ desc "Run tests"
9
+ task :default => :test
data/bin/csv2strings ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path('../../lib/command', __FILE__)
3
+
4
+
5
+ if ARGV.count == 1 && ARGV[0] == "help"
6
+ Command.start(["help", "csv2strings"],{})
7
+ else
8
+ args = ["csv2strings"]
9
+ args += ARGV
10
+ Command.start(args,{})
11
+ end
data/bin/strings2csv ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ require File.expand_path('../../lib/command', __FILE__)
3
+
4
+ if ARGV.count == 1 && ARGV[0] == "help"
5
+ Command.start(["help", "strings2csv"],{})
6
+ else
7
+ args = ["strings2csv"]
8
+ args += ARGV
9
+ Command.start(args,{})
10
+ end
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'csv2strings'
3
+ s.version = '0.2.0'
4
+ s.date = '2013-09-02'
5
+ s.summary = "CSV to iOS Localizable.strings converter"
6
+ s.description = "ruby script converts a CSV file of translations to Localizable.strings files and vice-versa"
7
+ s.authors = ["François Benaiteau"]
8
+ s.email = 'francois.benaiteau@gmail.com'
9
+ s.homepage = 'https://github.com/netbe/CSV-to-iOS-Localizable.strings-converter'
10
+ s.license = 'MIT'
11
+ s.add_dependency "thor"
12
+ s.add_dependency "fastercsv", :require => 'faster_csv' if RUBY_PLATFORM == 'ruby_19'
13
+ s.add_dependency "csv", :require => 'csv' if RUBY_PLATFORM == 'ruby_18'
14
+ s.add_development_dependency "rake"
15
+ s.add_development_dependency "mocha"
16
+ s.add_development_dependency "test-unit"
17
+ s.add_development_dependency "simplecov"
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_path = ['lib']
22
+ end
data/lib/command.rb ADDED
@@ -0,0 +1,66 @@
1
+ $: << File.expand_path(File.join(File.dirname(__FILE__)))
2
+ require 'yaml'
3
+ require 'thor'
4
+ require 'csvconverter'
5
+
6
+ class Command < Thor
7
+
8
+ desc "CSV_FILENAME", "convert CSV file to '.strings' file"
9
+ # required options but handled in method because of options read from yaml file
10
+ method_option :filename, :type => :string, :desc => "CSV file (CSV_FILENAME) to convert from"
11
+ method_option :langs, :type => :hash, :aliases => "-L", :desc => "Languages to convert"
12
+ # optional options
13
+ method_option :excluded_states, :type => :array, :aliases => "-x", :desc => "Exclude rows with given state"
14
+ method_option :state_column, :type => :numeric, :aliases => "-s", :desc => "Position of column for state if any"
15
+ method_option :keys_column, :type => :numeric, :aliases => "-k", :desc => "Position of column for keys"
16
+ method_option :default_lang, :type => :string, :aliases => "-l", :desc => "Default language to use for empty values if any"
17
+ method_option :default_path, :type => :string, :aliases => "-p", :desc => "Path of output files"
18
+ def csv2strings(filename = nil)
19
+ unless filename || options.has_key?('filename')
20
+ puts "No value provided for required options '--filename'"
21
+ help("csv2strings")
22
+ exit
23
+ end
24
+ unless options.has_key?('langs')
25
+ puts "No value provided for required options '--langs'"
26
+ help("csv2strings")
27
+ exit
28
+ end
29
+ filename ||= options['filename']
30
+ args = options.dup
31
+ args.delete(:langs)
32
+ args.delete(:filename)
33
+ converter = CSV2Strings::Converter.new(filename, options[:langs], args)
34
+ converter.csv_to_dotstrings
35
+ end
36
+
37
+ desc "FILENAMES", "convert '.strings' files to CSV file"
38
+ # required options but handled in method because of options read from yaml file
39
+ method_option :filenames, :type => :array, :aliases => "-i", :desc => "location of strings files (FILENAMES)"
40
+ # optional options
41
+ method_option :csv_filename, :type => :string, :aliases => "-o", :desc => "location of output file"
42
+ method_option :headers, :type => :array, :aliases => "-h", :desc => "override headers of columns, default is name of input files and 'Variables' for reference"
43
+ method_option :dryrun, :type => :boolean, :aliases => "-n", :desc => "prints out content of hash without writing file"
44
+ def strings2csv
45
+ unless options.has_key?('filenames')
46
+ puts "No value provided for required options '--filenames'"
47
+ help("strings2csv")
48
+ exit
49
+ end
50
+ converter = Strings2CSV::Converter.new(options)
51
+ debug_values = converter.dotstrings_to_csv(!options[:dryrun])
52
+ puts debug_values.inspect if options[:dryrun]
53
+ end
54
+
55
+ private
56
+ def options
57
+ original_options = super
58
+ return original_options unless File.exists?(".csvconverter")
59
+ defaults = ::YAML::load_file(".csvconverter") || {}
60
+ # add default values for options here
61
+ defaults["csv_filename"] = "translations.csv" unless defaults.has_key?("csv_filename")
62
+ defaults["dryrun"] = false unless defaults.has_key?("dryrun")
63
+ defaults["keys_column"] = 0 unless defaults.has_key?("keys_column")
64
+ Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
65
+ end
66
+ end
@@ -0,0 +1,130 @@
1
+ module CSV2Strings
2
+ class Converter
3
+ attr_accessor :csv_filename, :output_file
4
+ attr_accessor :langs, :default_lang
5
+ attr_accessor :default_path
6
+ attr_accessor :excluded_states, :state_column, :keys_column
7
+
8
+
9
+ def initialize(filename, langs, args = {})
10
+ args.merge!({
11
+ :excluded_states => [],
12
+ :state_column => nil,
13
+ :keys_column => 0})
14
+
15
+ @csv_filename = filename
16
+ @langs = langs
17
+
18
+ if !@langs.is_a?(Hash) || @langs.size == 0
19
+ raise "wrong format or/and languages parameter"
20
+ end
21
+ @output_file = (@langs.size == 1) ? args[:output_file] : nil
22
+
23
+ @default_path = args[:default_path].to_s
24
+ @excluded_states = args[:excluded_states]
25
+ @state_column = args[:state_column]
26
+ @keys_column = args[:keys_column]
27
+ @default_lang = args[:default_lang]
28
+ end
29
+
30
+ def create_file_from_path(file_path)
31
+ path = File.dirname(file_path)
32
+ FileUtils.mkdir_p path
33
+ return File.new(file_path,"w")
34
+ end
35
+
36
+ def process_header(excludedCols, files, row, index)
37
+ files[index] = []
38
+ lang_index = row[index]
39
+
40
+ # create output files here
41
+ if @output_file
42
+ # one single file
43
+ files[index] << self.create_file_from_path(@output_file)
44
+ else
45
+ # create one file for each languages
46
+ if self.langs[lang_index].is_a?(Array)
47
+
48
+ self.langs[lang_index].each do |locale|
49
+ filename = self.file_path_for_locale(locale)
50
+ files[index] << self.create_file_from_path(filename)
51
+ end
52
+ elsif self.langs[lang_index].is_a?(String)
53
+ locale = self.langs[lang_index]
54
+ filename = self.file_path_for_locale(locale)
55
+ files[index] << self.create_file_from_path(filename)
56
+ else
57
+ raise "wrong format or/and languages parameter"
58
+ end
59
+
60
+ end
61
+ end
62
+
63
+ def file_path_for_locale(locale)
64
+ require 'pathname'
65
+ Pathname.new(self.default_path) + "#{locale}.lproj" + "Localizable.strings"
66
+ end
67
+
68
+ def process_value(row_value, default_value)
69
+ value = row_value.nil? ? default_value : row_value
70
+ value = "" if value.nil?
71
+ value.gsub!(/\\*\"/, "\\\"") #escape double quotes
72
+ value.gsub!(/\s*(\n|\\\s*n)\s*/, "\\n") #replace new lines with \n + strip
73
+ value.gsub!(/%\s+([a-zA-Z@])([^a-zA-Z@]|$)/, "%\\1\\2") #repair string formats ("% d points" etc)
74
+ value.gsub!(/([^0-9\s\(\{\[^])%/, "\\1 %")
75
+ value.strip!
76
+ return value
77
+ end
78
+
79
+ # Convert csv file to multiple Localizable.strings files for each column
80
+ def csv_to_dotstrings(name = self.csv_filename)
81
+ files = {}
82
+ rowIndex = 0
83
+ excludedCols = []
84
+ defaultCol = 0
85
+ nb_translations = 0
86
+ CSVParserClass.foreach(name, :quote_char => '"', :col_sep =>',', :row_sep => :auto) do |row|
87
+
88
+ if rowIndex == 0
89
+ return unless row.count > 1 #check there's at least two columns
90
+ else
91
+ next if row == nil or row[self.keys_column].nil? #skip empty lines (or sections)
92
+ end
93
+
94
+ row.size.times do |i|
95
+ next if excludedCols.include? i
96
+ if rowIndex == 0 #header
97
+ # ignore all headers not listed in langs to create files
98
+ (excludedCols << i and next) unless self.langs.has_key?(row[i])
99
+ self.process_header(excludedCols, files, row, i)
100
+ # define defaultCol
101
+ defaultCol = i if self.default_lang == row[i]
102
+ elsif !self.state_column || (row[self.state_column].nil? or row[self.state_column] == '' or !self.excluded_states.include? row[self.state_column])
103
+ # TODO: add option to strip the constant or referenced language
104
+ key = row[self.keys_column].strip
105
+ value = self.process_value(row[i], row[defaultCol])
106
+ # files for a given language, i.e could group english US with english UK.
107
+ localized_files = files[i]
108
+ if localized_files
109
+ localized_files.each do |file|
110
+ nb_translations += 1
111
+ file.write "\"#{key}\" = \"#{value}\";\n"
112
+ end
113
+ end
114
+ end
115
+ end
116
+ rowIndex += 1
117
+ end
118
+ puts "\n>>>Created #{files.size} files. Content: #{nb_translations} translations\n"
119
+
120
+ # closing I/O
121
+ files.each do |key,locale_files|
122
+ locale_files.each do |file|
123
+ file.close
124
+ end
125
+ end
126
+
127
+ end # end of method
128
+
129
+ end # end of class
130
+ end
@@ -0,0 +1,16 @@
1
+ $: << File.expand_path(File.join(File.dirname(__FILE__)))
2
+ require 'rubygems'
3
+
4
+ CSVGEM = RUBY_VERSION.match(/^[0-1]\.[0-8]\./) ? 'faster_csv' : 'csv'
5
+
6
+ begin
7
+ require CSVGEM
8
+ rescue LoadError
9
+ puts "Failed to load #{CSVGEM} (ruby #{RUBY_VERSION})"
10
+ puts "gem install #{CSVGEM}"
11
+ exit
12
+ end
13
+
14
+ CSVParserClass = CSVGEM == 'csv' ? CSV : FasterCSV
15
+ require "csv2strings/converter"
16
+ require "strings2csv/converter"
@@ -0,0 +1,95 @@
1
+ module Strings2CSV
2
+ class Converter
3
+
4
+ attr_accessor :csv_filename, :headers, :filenames, :default_lang
5
+
6
+ def initialize(args = {:filenames => []})
7
+ if args[:filenames] && args[:headers]
8
+ raise ArgumentError.new("number of headers and files don't match, don't forget the constant column") unless args[:headers].size == (args[:filenames].size + 1)
9
+ end
10
+
11
+ @filenames = args[:filenames]
12
+
13
+ @csv_filename = args[:csv_filename] || "translations.csv"
14
+ @default_lang = args[:default_lang]
15
+ @headers = args[:headers] || self.default_headers
16
+ end
17
+
18
+ def default_headers
19
+ headers = ['Variables']
20
+ @filenames.each do |fname|
21
+ headers << basename(fname)
22
+ end
23
+ end
24
+
25
+
26
+ # Load all strings of a given file
27
+ def load_strings(strings_filename)
28
+ strings = {}
29
+ File.open(strings_filename, 'r') do |strings_file|
30
+ strings_file.read.each_line do |line|
31
+ strings.merge!(self.parse_dotstrings_line(line))
32
+ end
33
+ end
34
+ strings
35
+ end
36
+
37
+ def parse_dotstrings_line(line)
38
+ line.strip!
39
+ if (line[0] != ?# and line[0] != ?=)
40
+ m = line.match(/^[^\"]*\"(.+)\"[^=]+=[^\"]*\"(.*)\";/)
41
+ return {m[1] => m[2]} unless m.nil?
42
+ end
43
+ end
44
+
45
+
46
+ # Convert Localizable.strings files to one CSV file
47
+ # output:
48
+ def dotstrings_to_csv(write_to_file = true)
49
+ # Parse .strings files
50
+ strings = {}
51
+ keys = nil
52
+ lang_order = []
53
+
54
+ @filenames.each do |fname|
55
+ header = basename(fname)
56
+ strings[header] = load_strings(fname)
57
+ lang_order << header
58
+ keys ||= strings[header].keys
59
+ end
60
+
61
+ if(write_to_file)
62
+ # Create csv file
63
+ puts "Creating #{@csv_filename}"
64
+ create_csv_file(keys, lang_order, strings)
65
+ else
66
+ return keys, lang_order, strings
67
+ end
68
+ end
69
+
70
+ def basename(file_path)
71
+ filename = File.basename(file_path)
72
+ return filename.split('.')[0].to_sym if file_path
73
+ end
74
+
75
+ # Create the resulting file
76
+ def create_csv_file(keys, lang_order, strings)
77
+ raise "csv_filename must not be nil" unless self.csv_filename
78
+ CSVParserClass.open(self.csv_filename, "wb") do |csv|
79
+ csv << @headers
80
+ keys.each do |key|
81
+ line = [key]
82
+ default_val = strings[self.default_lang][key] if strings[self.default_lang]
83
+ lang_order.each do |lang|
84
+ current_val = strings[lang][key]
85
+ line << ((lang != self.default_lang and current_val == default_val) ? '' : current_val)
86
+ end
87
+ csv << line
88
+ end
89
+ puts "Done"
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+
@@ -0,0 +1,90 @@
1
+ require 'test_helper'
2
+
3
+ require 'command'
4
+ class CommandTest < Test::Unit::TestCase
5
+ def test_csv2strings_with_multiple_2_languages
6
+ command = "./bin/csv2strings"
7
+ command += " test/data/test_data_multiple_langs.csv"
8
+ command += " --langs=English:en French:fr"
9
+ system(command)
10
+
11
+ assert File.exist?("./en.lproj/Localizable.strings")
12
+ assert File.exist?("./fr.lproj/Localizable.strings")
13
+
14
+ #clean up
15
+ system("rm -rf ./en.lproj/")
16
+ system("rm -rf ./fr.lproj/")
17
+ end
18
+
19
+ def test_csv2strings_with_default_path
20
+ command = "./bin/csv2strings"
21
+ command += " test/data/test_data_multiple_langs.csv"
22
+ command += " --langs=English:en French:fr"
23
+ command += " --default_path=mynewlocation"
24
+ system(command)
25
+
26
+ # testing
27
+ assert File.exist?("./mynewlocation/en.lproj/Localizable.strings"), "can't find output file for English"
28
+ assert File.exist?("./mynewlocation/fr.lproj/Localizable.strings"), "can't find output file for French"
29
+
30
+ #clean up
31
+ system("rm -rf ./mynewlocation")
32
+ end
33
+
34
+ def test_strings2csv
35
+ command = "./bin/strings2csv"
36
+ command += " --filenames test/data/test_data.strings"
37
+ system(command)
38
+
39
+ assert File.exist?("translations.csv")
40
+
41
+ #clean up
42
+ system("rm -f translations.csv")
43
+ end
44
+
45
+ def test_strings2csv_with_dryrun_option
46
+ command = "./bin/strings2csv"
47
+ command += " --filenames test/data/test_data.strings"
48
+ command += " --dryrun"
49
+ system(command)
50
+
51
+ assert !File.exist?("translations.csv")
52
+
53
+ #clean up
54
+ system("rm -f translations.csv")
55
+ end
56
+
57
+ def test_strings2csv_with_output_file
58
+ command = "./bin/strings2csv"
59
+ command += " -i=test/data/test_data.strings"
60
+ command += " -o=myfile.csv"
61
+ system(command)
62
+
63
+ assert File.exist?("myfile.csv")
64
+
65
+ #clean up
66
+ system("rm -f myfile.csv")
67
+ end
68
+
69
+ def test_strings2csv_with_headers
70
+ command = "./bin/csv2strings strings2csv"
71
+ command += " -i=test/data/test_data.strings"
72
+ command += " -h=constants english"
73
+ system(command)
74
+
75
+ #TODO assertion or move test on at lib level
76
+
77
+ #clean up
78
+ system("rm -f translations.csv")
79
+ end
80
+
81
+ def test_strings2csv_with_two_files
82
+ command = "./bin/csv2strings strings2csv"
83
+ command += " --filenames=test/data/test_en.strings test/data/test_fr.strings"
84
+ command += " --headers=Constants English French"
85
+ command += " -o=enfr.csv"
86
+ system(command)
87
+ end
88
+
89
+ end
90
+
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../../../lib/csv2strings/converter', __FILE__)
2
+ require File.expand_path('../../test_helper', __FILE__)
3
+
4
+ class CSV2Strings::ConverterTest < Test::Unit::TestCase
5
+
6
+ def test_converting_csv_to_dotstrings
7
+ csv_file = "test/data/test_data.csv"
8
+ converter = CSV2Strings::Converter.new(csv_file, 'English' => [:en])
9
+ converter.csv_to_dotstrings
10
+ assert File.exists?("en.lproj/Localizable.strings"), "the ouptut file does not exist"
11
+ end
12
+
13
+ def test_converting_csv_to_dotstrings_one_output_option
14
+ csv_file = "test/data/test_data.csv"
15
+ single_file = 'myApp.strings'
16
+ converter = CSV2Strings::Converter.new(csv_file,
17
+ {'English' => [:en]},
18
+ :output_file => single_file)
19
+ converter.csv_to_dotstrings
20
+ assert File.exists?(single_file), "the ouptut file does not exist"
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ variables,English
2
+ ERROR_HANDLER_WARNING_DISMISS,OK
3
+ ANOTHER_STRING,hello
@@ -0,0 +1,2 @@
1
+ "ERROR_HANDLER_WARNING_DISMISS" = "OK";
2
+ "ANOTHER_STRING" = "hello";
@@ -0,0 +1,3 @@
1
+ variables,English,German,French,Spanish
2
+ GREETINGS,Hello,Hallo,Salut,Buenos dias
3
+ ANOTHER_STRING,testEN,,,
@@ -0,0 +1,2 @@
1
+ "GREETINGS" = "Hello";
2
+ "ANOTHER_STRING" = "testEN";
@@ -0,0 +1,2 @@
1
+ "GREETINGS" = "Bonjour";
2
+ "ANOTHER_STRING" = "testFR";
@@ -0,0 +1,96 @@
1
+ require File.expand_path('../../../lib/strings2csv/converter', __FILE__)
2
+ require File.expand_path('../../test_helper', __FILE__)
3
+
4
+ class Strings2CSV::ConverterTest < Test::Unit::TestCase
5
+
6
+ def test_parse_dotstrings_line_with_good_string
7
+ input = String.new(<<-EOS)
8
+ "MY_CONSTANT" = "This is ok";
9
+ EOS
10
+ expected_output = {"MY_CONSTANT"=>"This is ok"}
11
+
12
+ output = Strings2CSV::Converter.new.parse_dotstrings_line input
13
+ assert_equal output, expected_output
14
+ end
15
+
16
+ def test_parse_dotstrings_line_with_single_quote
17
+ input = String.new(<<-EOS)
18
+ "MY_CONSTANT" = "This 'is' ok";
19
+ EOS
20
+ expected_output = {"MY_CONSTANT"=>"This 'is' ok"}
21
+
22
+ output = Strings2CSV::Converter.new.parse_dotstrings_line input
23
+ assert_equal output, expected_output
24
+ end
25
+
26
+ def test_parse_dotstrings_line_with_double_quotes
27
+ input = String.new(<<-EOS)
28
+ "MY_CONSTANT" = "This "is" ok";
29
+ EOS
30
+ expected_output = {"MY_CONSTANT"=>"This \"is\" ok"}
31
+
32
+ output = Strings2CSV::Converter.new.parse_dotstrings_line input
33
+ assert_equal output, expected_output
34
+ end
35
+
36
+ def test_parse_dotstrings_line_with_wrong_string
37
+ input = String.new(<<-EOS)
38
+ "MY_CONSTANT" = "wrong syntax"
39
+ EOS
40
+
41
+ output = Strings2CSV::Converter.new.parse_dotstrings_line input
42
+ assert_nil output, "output should be nil with wrong syntax"
43
+ end
44
+
45
+ def test_load_strings_with_wrong_file
46
+ assert_raise(Errno::ENOENT) do
47
+ output = Strings2CSV::Converter.new.load_strings "file that does not exist.strings"
48
+ end
49
+ end
50
+
51
+ def test_load_strings
52
+ expected_output = {"ERROR_HANDLER_WARNING_DISMISS" => "OK", "ANOTHER_STRING" => "hello"}
53
+ output = Strings2CSV::Converter.new.load_strings "test/data/test_data.strings"
54
+ assert_equal expected_output, output
55
+ end
56
+
57
+ def test_dotstrings_to_csv
58
+ converter = Strings2CSV::Converter.new(:filenames => ["test/data/test_data.strings"])
59
+ keys, lang_order, strings = converter.dotstrings_to_csv(false)
60
+ assert_equal ["test_data".to_sym], lang_order
61
+ assert_equal ["ERROR_HANDLER_WARNING_DISMISS", "ANOTHER_STRING"], keys
62
+ expected_strings = {lang_order[0] => {"ERROR_HANDLER_WARNING_DISMISS" => "OK", "ANOTHER_STRING" => "hello"}}
63
+ assert_equal expected_strings, strings
64
+ end
65
+
66
+ def test_create_csv_file
67
+ keys = ["ERROR_HANDLER_WARNING_DISMISS", "ANOTHER_STRING"]
68
+ lang_order = [:"test_data"]
69
+ strings = {lang_order[0] => {"ERROR_HANDLER_WARNING_DISMISS" => "OK", "ANOTHER_STRING" => "hello"}}
70
+
71
+ converter = Strings2CSV::Converter.new(:headers => %w{variables english})
72
+
73
+ converter.create_csv_file(keys, lang_order, strings)
74
+ assert File.exist?(converter.csv_filename)
75
+ end
76
+
77
+ def test_initialize
78
+ csv_filename = "file.csv"
79
+ filenames = %w{"french.strings english.strings"}
80
+ headers = %w{"constants french english"}
81
+ converter = Strings2CSV::Converter.new({
82
+ :csv_filename => csv_filename,
83
+ :headers => headers,
84
+ :filenames => filenames
85
+ })
86
+
87
+ assert_equal csv_filename, converter.csv_filename
88
+ assert_equal headers, converter.headers
89
+ assert_equal filenames, converter.filenames
90
+ end
91
+
92
+ def test_initialize_with_default_values
93
+ converter = Strings2CSV::Converter.new
94
+ assert_not_nil converter.csv_filename
95
+ end
96
+ end
@@ -0,0 +1,12 @@
1
+ begin
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter "test"
5
+ end
6
+ rescue LoadError
7
+ puts 'Coverage disabled, enable by installing simplecov'
8
+ end
9
+
10
+ require 'test/unit'
11
+ require "mocha"
12
+
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csv2strings
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - François Benaiteau
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mocha
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: ruby script converts a CSV file of translations to Localizable.strings
84
+ files and vice-versa
85
+ email: francois.benaiteau@gmail.com
86
+ executables:
87
+ - csv2strings
88
+ - strings2csv
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - .csvconverter.sample
93
+ - .gitignore
94
+ - .travis.yml
95
+ - Gemfile
96
+ - Gemfile.lock
97
+ - LICENSE.txt
98
+ - README.md
99
+ - Rakefile
100
+ - bin/csv2strings
101
+ - bin/strings2csv
102
+ - csv2strings.gemspec
103
+ - lib/command.rb
104
+ - lib/csv2strings/converter.rb
105
+ - lib/csvconverter.rb
106
+ - lib/strings2csv/converter.rb
107
+ - test/command_test.rb
108
+ - test/csv2strings/converter_test.rb
109
+ - test/data/test_data.csv
110
+ - test/data/test_data.strings
111
+ - test/data/test_data_multiple_langs.csv
112
+ - test/data/test_en.strings
113
+ - test/data/test_fr.strings
114
+ - test/strings2csv/converter_test.rb
115
+ - test/test_helper.rb
116
+ homepage: https://github.com/netbe/CSV-to-iOS-Localizable.strings-converter
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.0.0
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: CSV to iOS Localizable.strings converter
140
+ test_files:
141
+ - test/command_test.rb
142
+ - test/csv2strings/converter_test.rb
143
+ - test/data/test_data.csv
144
+ - test/data/test_data.strings
145
+ - test/data/test_data_multiple_langs.csv
146
+ - test/data/test_en.strings
147
+ - test/data/test_fr.strings
148
+ - test/strings2csv/converter_test.rb
149
+ - test/test_helper.rb