bisu 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f4cb23115b4c94bf3388f524bcdff21ebef2f2a
4
+ data.tar.gz: d8357042c4d597977ceb6a6831138ed91422f11f
5
+ SHA512:
6
+ metadata.gz: c6e844bba80f1e2e38ecbd71b4f2d605e04ac863c751901c01954d7f58cac6fecfc6d87db4f6ad211eb0a221e2dea13372fba4d969227af2002776c02d39a27e
7
+ data.tar.gz: c1079b0db9e927d803eb612376d7907682d0b19cc91242c2ff2746f7ebe298db4e55dd2bfa64dda8a405f3b016caf3600764950349c45a4bf7d4bd30993e6ca6
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ H19-Bisu
2
+ ========
3
+
4
+ Bisu manages your app iOS and Android localization files for you. No more copy+paste induced errors!
5
+
6
+ ---
7
+
8
+ Instalation
9
+ -----
10
+
11
+ 1. Download gem file: [bisu.gem](https://github.com/hole19/h19-bisu/blob/master/bisu.gem?raw=true)
12
+ 1. Run in terminal: `gem install path/to/bisu.gem`
13
+
14
+ Usage
15
+ -----
16
+
17
+ 1. Open terminal in app project base
18
+ 1. Run: `bisu`
19
+ 1. That's it!*
20
+
21
+ *given that someone already configured Bisu
22
+
23
+ Configuration
24
+ -----
25
+
26
+ 1. Create in your **iOS/Android** app project base folder a translatable.yml:
27
+
28
+ ```
29
+ type: <iOS/Android>
30
+
31
+ sheet_id: <GOOGLE-DRIVE-SHEET-ID>
32
+ keys_column: <GOOGLE-DRIVE-KEY-COLUMN-TITLE>
33
+
34
+ in:
35
+ - path/to/1st/file.translatable
36
+ - path/to/2nd/file.translatable
37
+
38
+ out:
39
+ - language: english
40
+ folder: path/to/en.lproj/
41
+ - language: korean
42
+ folder: path/to/ko.lproj/
43
+ ```
44
+
45
+ 1. Replace your **iOS** localization files with *.translatable* versions:
46
+
47
+ ```
48
+ // $specialKComment1$
49
+ // $specialKComment2$
50
+
51
+ // $specialKLanguage$
52
+
53
+ /***********
54
+ * General
55
+ ************/
56
+
57
+ "klGeneral_Delete" = "$kDelete$";
58
+ "klGeneral_Cancel" = "$kCancel$";
59
+ "klGeneral_Close" = "$kClose$";
60
+ ```
61
+
62
+ 1. Replace your **Android** localization files with *.translatable* versions:
63
+
64
+ ```
65
+ <?xml version="1.0" encoding="utf-8"?>
66
+
67
+ <!-- $specialKComment1$ -->
68
+ <!-- $specialKComment2$ -->
69
+ <!-- $specialKLanguage$ -->
70
+
71
+ <resources>
72
+ <string name="delete">$kDelete$</string>
73
+ <string name="cancel">$kCancel$</string>
74
+ <string name="close">$kClose$</string>
75
+ </resources>
76
+ ```
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
data/bin/bisu ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bisu'
4
+ Bisu.run
data/bisu.gem ADDED
Binary file
data/bisu.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'bisu'
3
+ s.version = '1.0.0'
4
+ s.date = '2015-01-28'
5
+ s.summary = 'Bisu - localization automation service'
6
+ s.description = 'Bisu is a localization automation service. It was built specially for Hole19'
7
+ s.authors = ['joaoffcosta']
8
+ s.email = 'joao.costa@hole19golf.com'
9
+ s.license = 'MIT'
10
+ s.homepage = 'https://github.com/hole19/h19-bisu'
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.require_paths = ['lib']
14
+
15
+ s.executables << 'bisu'
16
+
17
+ s.add_runtime_dependency 'safe_yaml', '~> 1.0'
18
+ s.add_runtime_dependency 'colorize', '~> 0.7'
19
+
20
+ s.add_development_dependency 'webmock', '~> 1.20'
21
+ end
@@ -0,0 +1,38 @@
1
+ require "yaml"
2
+
3
+ module Bisu
4
+ module Config
5
+ extend self
6
+
7
+ def parse(file_name)
8
+ unless file_name
9
+ Logger.error("Config file not provided")
10
+ return nil
11
+ end
12
+
13
+ unless File.exists?(file_name)
14
+ Logger.error("Could not find config file #{file_name}")
15
+ return nil
16
+ end
17
+
18
+ begin
19
+ deep_sym(YAML::load_file(file_name))
20
+ rescue Exception => e
21
+ Logger.error("Could not parse config file #{file_name}: #{e}")
22
+ return nil
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def deep_sym(obj)
29
+ if obj.is_a?(Array)
30
+ obj.map { |v| deep_sym(v) }
31
+ elsif obj.is_a?(Hash)
32
+ obj.inject({}) { |memo, (k,v)| memo[k.to_sym] = deep_sym(v); memo }
33
+ else
34
+ obj
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,72 @@
1
+ require "net/https"
2
+ require "xmlsimple"
3
+
4
+ module Bisu
5
+
6
+ class KnowledgeBase
7
+ def initialize(kb)
8
+ raise "Bad KB format (expected Hash)" unless kb.is_a?(Hash)
9
+ raise "Bad KB format (expected :languages Array)" unless kb.key?(:languages) && kb[:languages].is_a?(Array)
10
+ raise "Bad KB format (expected :keys Hash)" unless kb.key?(:keys) && kb[:keys].is_a?(Hash)
11
+ @kb = kb
12
+ end
13
+
14
+ def has_language?(language)
15
+ @kb[:languages].include?(language)
16
+ end
17
+
18
+ def localize(key, language)
19
+ if locals = @kb[:keys][key]
20
+ locals[language]
21
+ else
22
+ nil
23
+ end
24
+ end
25
+ end
26
+
27
+
28
+ class GoogleDriveKB < KnowledgeBase
29
+ def initialize(sheet_id, keys_column_title)
30
+ raw = raw_data(sheet_id)
31
+ kb = parse(raw, keys_column_title)
32
+ super(kb)
33
+ end
34
+
35
+ private
36
+
37
+ def feed_data(uri, headers=nil)
38
+ uri = URI.parse(uri)
39
+ http = Net::HTTP.new(uri.host, uri.port)
40
+ http.use_ssl = true
41
+ data = http.get(uri.path, headers)
42
+ XmlSimple.xml_in(data.body, 'KeyAttr' => 'name')
43
+ end
44
+
45
+ def raw_data(sheet_id)
46
+ Logger.info("Downloading Knowledge Base...")
47
+ sheet = feed_data("https://spreadsheets.google.com/feeds/worksheets/#{sheet_id}/public/full")
48
+ feed_data(sheet["entry"][0]["link"][0]["href"])
49
+ end
50
+
51
+ def parse(raw_data, key)
52
+ Logger.info("Parsing Knowledge Base...")
53
+
54
+ remove = ["id", "updated", "category", "title", "content", "link", key]
55
+
56
+ kb_keys = {}
57
+ raw_data["entry"].each do |entry|
58
+ hash = entry.select { |d| !remove.include?(d) }
59
+ hash = hash.each.map { |k, v| v.first == {} ? [k, nil] : [k, v.first] }
60
+ kb_keys[entry[key].first] = Hash[hash]
61
+ end
62
+
63
+ kb = { languages: kb_keys.values.first.keys, keys: kb_keys }
64
+
65
+ Logger.info("Knowledge Base parsed successfully!")
66
+ Logger.info("Found #{kb[:keys].count} keys in #{kb[:languages].count} languages.")
67
+
68
+ kb
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,61 @@
1
+ require "singleton"
2
+ require "colorize"
3
+
4
+ module Bisu
5
+ module Logger
6
+ extend self
7
+
8
+ def info(msg)
9
+ log :info, msg
10
+ end
11
+
12
+ def warn(msg)
13
+ log :warn, msg
14
+ end
15
+
16
+ def error(msg)
17
+ log :error, msg
18
+ end
19
+
20
+ def clean_summary
21
+ @levels.each { |k, _| @levels[k] = 0 }
22
+ end
23
+
24
+ def summary
25
+ @levels
26
+ end
27
+
28
+ def print_summary
29
+ if @levels[:warn] > 0 || @levels[:error] > 0
30
+ info ""
31
+ info "Finished with:"
32
+ info " #{@levels[:warn]} warnings" if @levels[:warn] > 0
33
+ info " #{@levels[:error]} errors" if @levels[:error] > 0
34
+ info ""
35
+ end
36
+ end
37
+
38
+ def silent_mode=(value)
39
+ @silent_mode = value
40
+ end
41
+
42
+ private
43
+
44
+ @levels = { info: 0, warn: 0, error: 0 }
45
+ @silent_mode = false
46
+
47
+ def log(level, msg)
48
+ unless @levels.keys.include?(level)
49
+ return log(:error, "Unknown log level: #{level}")
50
+ end
51
+
52
+ @levels[level] += 1
53
+
54
+ msg = "[#{level.upcase}] #{msg}"
55
+ msg = msg.yellow if level.eql?(:warn)
56
+ msg = msg.red if level.eql?(:error)
57
+
58
+ puts msg unless @silent_mode
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,93 @@
1
+ module Bisu
2
+ class Translator
3
+ def initialize(knowledge_base, type)
4
+ @kb = knowledge_base
5
+ @type = type.downcase.to_sym
6
+
7
+ unless [:ios, :android].include?(@type)
8
+ Logger.error("Unknown type #{@type}")
9
+ raise
10
+ end
11
+ end
12
+
13
+ def translate(language, in_path, out_folder)
14
+ unless @kb.has_language?(language)
15
+ Logger.error("Unknown language #{language}")
16
+ return false
17
+ end
18
+
19
+ in_name = File.basename(in_path)
20
+ out_name = in_name.gsub(/\.translatable$/, "")
21
+ out_path = "#{out_folder}#{out_name}"
22
+
23
+ unless in_name.match /\.translatable$/
24
+ Logger.error("Expected .translatable file. Got '#{in_name}'")
25
+ return false
26
+ end
27
+
28
+ return false unless in_file = open_file(in_path, "r", true)
29
+ return false unless out_file = open_file(out_path, "w", false, true)
30
+
31
+ Logger.info("Translating #{in_path} to #{language} > #{out_path}...")
32
+
33
+ in_file.each_line do |line|
34
+ out_file.write(localize(line, language))
35
+ end
36
+
37
+ out_file.flush
38
+ out_file.close
39
+ in_file.close
40
+
41
+ true
42
+ end
43
+
44
+ private
45
+
46
+ def open_file(file_name, method, should_exist, can_overwrite=false)
47
+ if should_exist == File.file?(File.expand_path(file_name))
48
+ File.open(File.expand_path(file_name), method)
49
+
50
+ elsif should_exist
51
+ Logger.error("File #{file_name} not found!")
52
+ nil
53
+
54
+ elsif can_overwrite
55
+ File.open(File.expand_path(file_name), method)
56
+
57
+ elsif !should_exist
58
+ Logger.error("File #{file_name} already exists!")
59
+ nil
60
+ end
61
+ end
62
+
63
+ def localize(text, language)
64
+ t = text
65
+ t = t.gsub("$specialKLanguage$", language.upcase)
66
+ t = t.gsub("$specialKComment1$", "This file was automatically generated based on a translation template.")
67
+ t = t.gsub("$specialKComment2$", "Remember to CHANGE THE TEMPLATE and not this file!")
68
+
69
+ t = t.gsub(/\$(k[^\$]+)\$/) do |match|
70
+ if localized = @kb.localize("#{$1}", language)
71
+ process(localized)
72
+ else
73
+ match
74
+ end
75
+ end
76
+
77
+ t.scan(/\$k[^\$]+\$/) { |match| Logger.warn("Could not find translation for #{match} in #{language}") }
78
+
79
+ t
80
+ end
81
+
82
+ def process(text)
83
+ if @type.eql?(:android)
84
+ text = text.gsub(/[']/, "\\\\'")
85
+ text = text.gsub("...", "…")
86
+ text = text.gsub("& ", "&amp; ")
87
+
88
+ elsif @type.eql?(:ios)
89
+ text = text.gsub(/\"/, "\\\\\"")
90
+ end
91
+ end
92
+ end
93
+ end
data/lib/bisu.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'bisu/logger'
2
+ require 'bisu/config'
3
+ require 'bisu/knowledge_base'
4
+ require 'bisu/translator'
5
+
6
+ module Bisu
7
+ def self.run
8
+ if config = Bisu::Config.parse("translatable.yml")
9
+ kbase = Bisu::GoogleDriveKB.new(config[:sheet_id], config[:keys_column])
10
+ trans = Bisu::Translator.new(kbase, config[:type])
11
+
12
+ config[:in].each do |in_path|
13
+ config[:out].each do |out|
14
+ trans.translate(out[:language], in_path, out[:folder])
15
+ end
16
+ end
17
+ end
18
+
19
+ Bisu::Logger.print_summary
20
+ end
21
+ end
@@ -0,0 +1 @@
1
+ <?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gs='http://schemas.google.com/spreadsheets/2006'><id>https://spreadsheets.google.com/feeds/worksheets/abc1234567890/public/full</id><updated>2015-02-09T18:59:53.874Z</updated><category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#worksheet'/><title type='text'>H19: Translation Knowledge Base</title><link rel='alternate' type='application/atom+xml' href='https://docs.google.com/spreadsheets/d/abc1234567890/pubhtml'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/worksheets/abc1234567890/public/full'/><link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/worksheets/abc1234567890/public/full'/><link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/worksheets/abc1234567890/public/full'/><author><name>anthony.douglas</name><email>anthony.douglas@hole19golf.com</email></author><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><entry><id>https://spreadsheets.google.com/feeds/worksheets/abc1234567890/public/full/od6</id><updated>2015-02-09T18:59:53.874Z</updated><category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#worksheet'/><title type='text'>Translations</title><content type='text'>Translations</content><link rel='http://schemas.google.com/spreadsheets/2006#listfeed' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full'/><link rel='http://schemas.google.com/spreadsheets/2006#cellsfeed' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/cells/abc1234567890/od6/public/full'/><link rel='http://schemas.google.com/visualization/2008#visualizationApi' type='application/atom+xml' href='https://docs.google.com/spreadsheets/d/abc1234567890/gviz/tq?gid=0&amp;pub=1'/><link rel='http://schemas.google.com/spreadsheets/2006#exportcsv' type='text/csv' href='https://docs.google.com/spreadsheets/d/abc1234567890/export?gid=0&amp;format=csv'/><link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/worksheets/abc1234567890/public/full/od6'/><gs:colCount>25</gs:colCount><gs:rowCount>665</gs:rowCount></entry></feed>
@@ -0,0 +1 @@
1
+ <?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'><id>https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full</id><updated>2015-02-09T18:59:53.874Z</updated><category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#list'/><title type='text'>Translations</title><link rel='alternate' type='application/atom+xml' href='https://docs.google.com/spreadsheets/d/abc1234567890/pubhtml'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full'/><link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full'/><link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full'/><author><name>anthony.douglas</name><email>anthony.douglas@hole19golf.com</email></author><openSearch:totalResults>664</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><entry><id>https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full/cokwr</id><updated>2015-02-09T18:59:53.874Z</updated><category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#list'/><title type='text'>kConnectFacebook</title><content type='text'>english: Connect with Facebook, german: Mit Facebook verbinden, portuguese: Registar com Facebook, spanish: Conéctate con Facebook, french: Connecter Facebook, dutch: Facebook Verbinden, korean: 페이스북으로 접속, japanese: フェイスブックへ接続, key_column_2: kConnectFacebook</content><link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full/cokwr'/><gsx:key_column>kConnectFacebook</gsx:key_column><gsx:english>Connect with Facebook</gsx:english><gsx:german>Mit Facebook verbinden</gsx:german><gsx:portuguese>Registar com Facebook</gsx:portuguese><gsx:spanish>Conéctate con Facebook</gsx:spanish><gsx:french>Connecter Facebook</gsx:french><gsx:dutch>Facebook Verbinden</gsx:dutch><gsx:korean>페이스북으로 접속</gsx:korean><gsx:japanese>フェイスブックへ接続</gsx:japanese><gsx:key_column_2>kConnectFacebook</gsx:key_column_2></entry><entry><id>https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full/cpzh4</id><updated>2015-02-09T18:59:53.874Z</updated><category scheme='http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#list'/><title type='text'>kConnectEmail</title><content type='text'>english: Connect with Email, german: Mit E-Mail verbinden, portuguese: Registar com Email, spanish: Conéctate con Email, french: Connecter Email, dutch: Email Verbinden, korean: 이메일로 접속, japanese: 電子メールアカウントに接続, key_column_2: kConnectEmail</content><link rel='self' type='application/atom+xml' href='https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full/cpzh4'/><gsx:key_column>kConnectEmail</gsx:key_column><gsx:english>Connect with Email</gsx:english><gsx:german>Mit E-Mail verbinden</gsx:german><gsx:portuguese>Registar com Email</gsx:portuguese><gsx:spanish>Conéctate con Email</gsx:spanish><gsx:french>Connecter Email</gsx:french><gsx:dutch>Email Verbinden</gsx:dutch><gsx:korean>이메일로 접속</gsx:korean><gsx:japanese>電子メールアカウントに接続</gsx:japanese><gsx:key_column_2>kConnectEmail</gsx:key_column_2></entry></feed>
@@ -0,0 +1,14 @@
1
+ type: iOS
2
+
3
+ sheet_id: abc1234567890
4
+ keys_column: key_name
5
+
6
+ in:
7
+ - folder/file_1.translatable
8
+ - folder/file_2.translatable
9
+
10
+ out:
11
+ - language: english
12
+ folder: hole19/en.lproj/
13
+ - language: portuguese
14
+ folder: hole19/pt.lproj/
@@ -0,0 +1,23 @@
1
+ require 'minitest/autorun'
2
+ require 'bisu/config'
3
+
4
+ class BisuConfigTest < Minitest::Test
5
+
6
+ def test_parse
7
+ config = Bisu::Config.parse("test/support/sample_translatable.yml")
8
+
9
+ assert_equal config[:type], "iOS"
10
+ assert_equal config[:sheet_id], "abc1234567890"
11
+ assert_equal config[:keys_column], "key_name"
12
+
13
+ assert_equal config[:in], [
14
+ "folder/file_1.translatable",
15
+ "folder/file_2.translatable"
16
+ ]
17
+
18
+ assert_equal config[:out], [
19
+ { language: "english", folder: "hole19/en.lproj/" },
20
+ { language: "portuguese", folder: "hole19/pt.lproj/" }
21
+ ]
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ require 'minitest/autorun'
2
+ require 'bisu/knowledge_base'
3
+
4
+ class BisuKnowledgeBaseTest < Minitest::Test
5
+
6
+ def test_parsing
7
+ stub_request(:get, "https://spreadsheets.google.com/feeds/worksheets/abc1234567890/public/full").to_return(
8
+ status: 200, body: File.read("test/support/sample_kb_public_info.html"), headers: {})
9
+
10
+ stub_request(:get, "https://spreadsheets.google.com/feeds/list/abc1234567890/od6/public/full").to_return(
11
+ status: 200, body: File.read("test/support/sample_kb_public_sheet.html"), headers: {})
12
+
13
+ Bisu::Logger.silent_mode = true
14
+
15
+ Bisu::GoogleDriveKB.new("abc1234567890", "key_column")
16
+
17
+ Bisu::Logger.silent_mode = false
18
+ end
19
+
20
+ def test_has_language?
21
+ kb = Bisu::KnowledgeBase.new({
22
+ languages: ["portuguese"],
23
+ keys: {}
24
+ })
25
+
26
+ assert_equal kb.has_language?("kriolo"), false
27
+ assert_equal kb.has_language?("portuguese"), true
28
+ end
29
+
30
+ def test_localize
31
+ key = "kYouKnowNothingJohnSnow"
32
+ pt_trans = "Não sabes nada João das Neves"
33
+
34
+ kb = Bisu::KnowledgeBase.new({
35
+ languages: ["portuguese"],
36
+ keys: { key => { "portuguese" => pt_trans } }
37
+ })
38
+
39
+ assert_equal kb.localize(key, "kriolo"), nil
40
+ assert_equal kb.localize(key, "portuguese"), pt_trans
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ require 'minitest/autorun'
2
+ require 'bisu/logger'
3
+
4
+ class BisuLoggerTest < Minitest::Test
5
+
6
+ def test_print_summary
7
+ Bisu::Logger.clean_summary
8
+ Bisu::Logger.silent_mode = true
9
+
10
+ 1.times { Bisu::Logger.info "info" }
11
+ 2.times { Bisu::Logger.warn "warn" }
12
+ 3.times { Bisu::Logger.error "error" }
13
+
14
+ Bisu::Logger.silent_mode = false
15
+
16
+ sum = Bisu::Logger.summary
17
+
18
+ assert_equal sum[:info], 1
19
+ assert_equal sum[:warn], 2
20
+ assert_equal sum[:error], 3
21
+ end
22
+ end
@@ -0,0 +1,53 @@
1
+ require 'minitest/autorun'
2
+ require 'bisu/translator'
3
+
4
+ class BisuTranslatorTest < Minitest::Test
5
+
6
+ def setup
7
+ kb = Bisu::KnowledgeBase.new({
8
+ languages: ["PT"],
9
+ keys: {
10
+ "kRegularKey" => { "PT" => "Não sabes nada João das Neves" },
11
+ "kIOSKey" => { "PT" => "Não sabes nada \"João das Neves\"" },
12
+ "kAndroidKey1" => { "PT" => "Não sabes nada 'João das Neves'" },
13
+ "kAndroidKey2" => { "PT" => "Não sabes nada João das Neves..." },
14
+ "kAndroidKey3" => { "PT" => "Não sabes nada João das Neves & Pícaros" },
15
+ }
16
+ })
17
+
18
+ @tios = Bisu::Translator.new(kb, :ios)
19
+ @tand = Bisu::Translator.new(kb, :android)
20
+ end
21
+
22
+ def test_simple_translate
23
+ orig1 = "1: $specialKComment1$"
24
+ orig2 = "2: $specialKComment2$"
25
+ orig3 = "3: $specialKLanguage$"
26
+ orig4 = "4: $kRegularKey$"
27
+
28
+ loc1 = "1: This file was automatically generated based on a translation template."
29
+ loc2 = "2: Remember to CHANGE THE TEMPLATE and not this file!"
30
+ loc3 = "3: PT"
31
+ loc4 = "4: Não sabes nada João das Neves"
32
+
33
+ assert_equal @tios.send(:localize, orig1, "PT"), loc1
34
+ assert_equal @tios.send(:localize, orig2, "PT"), loc2
35
+ assert_equal @tios.send(:localize, orig3, "PT"), loc3
36
+ assert_equal @tios.send(:localize, orig4, "PT"), loc4
37
+
38
+ assert_equal @tand.send(:localize, orig1, "PT"), loc1
39
+ assert_equal @tand.send(:localize, orig2, "PT"), loc2
40
+ assert_equal @tand.send(:localize, orig3, "PT"), loc3
41
+ assert_equal @tand.send(:localize, orig4, "PT"), loc4
42
+ end
43
+
44
+ def test_ios_translate
45
+ assert_equal @tios.send(:localize, "1: $kIOSKey$", "PT"), "1: Não sabes nada \\\"João das Neves\\\""
46
+ end
47
+
48
+ def test_android_translate
49
+ assert_equal @tand.send(:localize, "1: $kAndroidKey1$", "PT"), "1: Não sabes nada \\'João das Neves\\'"
50
+ assert_equal @tand.send(:localize, "2: $kAndroidKey2$", "PT"), "2: Não sabes nada João das Neves…"
51
+ assert_equal @tand.send(:localize, "3: $kAndroidKey3$", "PT"), "3: Não sabes nada João das Neves &amp; Pícaros"
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ require 'webmock/minitest'
2
+
3
+ WebMock.disable_net_connect!
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bisu
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - joaoffcosta
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: safe_yaml
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: webmock
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.20'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.20'
55
+ description: Bisu is a localization automation service. It was built specially for
56
+ Hole19
57
+ email: joao.costa@hole19golf.com
58
+ executables:
59
+ - bisu
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - README.md
64
+ - Rakefile
65
+ - bin/bisu
66
+ - bisu.gem
67
+ - bisu.gemspec
68
+ - lib/bisu.rb
69
+ - lib/bisu/config.rb
70
+ - lib/bisu/knowledge_base.rb
71
+ - lib/bisu/logger.rb
72
+ - lib/bisu/translator.rb
73
+ - test/support/sample_kb_public_info.html
74
+ - test/support/sample_kb_public_sheet.html
75
+ - test/support/sample_translatable.yml
76
+ - test/test_bisu_config.rb
77
+ - test/test_bisu_knowledge_base.rb
78
+ - test/test_bisu_logger.rb
79
+ - test/test_bisu_translator.rb
80
+ - test/test_helper.rb
81
+ homepage: https://github.com/hole19/h19-bisu
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.2.2
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Bisu - localization automation service
105
+ test_files: []