logaling-command 0.0.2 → 0.0.3
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 +1 -0
- data/lib/logaling/command.rb +58 -34
- data/lib/logaling/glossary.rb +28 -29
- data/lib/logaling/glossary_db.rb +29 -4
- data/spec/logaling/command_spec.rb +65 -13
- data/spec/logaling/glossary_db_spec.rb +103 -0
- data/spec/logaling/glossary_spec.rb +162 -33
- metadata +12 -10
data/.gitignore
CHANGED
data/lib/logaling/command.rb
CHANGED
|
@@ -2,57 +2,90 @@
|
|
|
2
2
|
|
|
3
3
|
require 'thor'
|
|
4
4
|
require "logaling/glossary"
|
|
5
|
-
require "logaling/glossary_db"
|
|
6
5
|
|
|
7
6
|
class Logaling::Command < Thor
|
|
8
|
-
VERSION = "0.0.
|
|
7
|
+
VERSION = "0.0.3"
|
|
8
|
+
LOGALING_CONFIG = '.logaling'
|
|
9
9
|
|
|
10
10
|
map '-c' => :create,
|
|
11
11
|
'-a' => :add,
|
|
12
12
|
'-d' => :delete,
|
|
13
13
|
'-u' => :update,
|
|
14
|
-
'-l' => :lookup
|
|
14
|
+
'-l' => :lookup,
|
|
15
|
+
'-n' => :new,
|
|
16
|
+
'-L' => :link
|
|
15
17
|
|
|
16
18
|
class_option "glossary", type: :string, aliases: "-g"
|
|
17
19
|
class_option "source-language", type: :string, aliases: "-S"
|
|
18
20
|
class_option "target-language", type: :string, aliases: "-T"
|
|
19
21
|
class_option "logaling-home", type: :string, required: false, aliases: "-h"
|
|
20
22
|
|
|
23
|
+
desc 'new [PROJECT NAME] [SOURCE LANGUAGE] [TARGET LANGUAGE(optional)]', 'Create .logaling'
|
|
24
|
+
def new(project_name, source_language, target_language=nil)
|
|
25
|
+
unless File.exist?(LOGALING_CONFIG)
|
|
26
|
+
FileUtils.mkdir_p(File.join(LOGALING_CONFIG, "glossary"))
|
|
27
|
+
File.open(File.join(LOGALING_CONFIG, "config"), 'w') do |config|
|
|
28
|
+
config.puts "--glossary #{project_name}"
|
|
29
|
+
config.puts "--source-language #{source_language}"
|
|
30
|
+
config.puts "--target-language #{target_language}" if target_language
|
|
31
|
+
end
|
|
32
|
+
say "Successfully created #{LOGALING_CONFIG}"
|
|
33
|
+
else
|
|
34
|
+
say "#{LOGALING_CONFIG} is already exists."
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
desc 'link', 'Link .logaling'
|
|
39
|
+
def link
|
|
40
|
+
logaling_path = find_dotfile
|
|
41
|
+
if logaling_path
|
|
42
|
+
logaling_projects_path = File.join(LOGALING_HOME, "projects")
|
|
43
|
+
FileUtils.mkdir_p(logaling_projects_path) unless File.exist?(logaling_projects_path)
|
|
44
|
+
|
|
45
|
+
config = load_config
|
|
46
|
+
symlink_path = File.join(logaling_projects_path, config["glossary"])
|
|
47
|
+
unless File.exists?(symlink_path)
|
|
48
|
+
FileUtils.ln_s(logaling_path, symlink_path)
|
|
49
|
+
say "Your project is now linked to #{symlink_path}."
|
|
50
|
+
else
|
|
51
|
+
say "#{options["glossary"]} is already linked."
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
say "Try 'loga new' first."
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
21
58
|
desc 'create', 'Create glossary.'
|
|
22
59
|
def create
|
|
23
|
-
load_config
|
|
24
60
|
glossary.create
|
|
25
61
|
rescue Logaling::CommandFailed => e
|
|
26
62
|
error(e.message)
|
|
27
63
|
end
|
|
28
64
|
|
|
29
|
-
desc 'add [
|
|
65
|
+
desc 'add [SOURCE TERM] [TARGET TERM] [NOTE(optional)]', 'Add term to glossary.'
|
|
30
66
|
def add(source_term, target_term, note='')
|
|
31
|
-
load_config
|
|
32
67
|
glossary.add(source_term, target_term, note)
|
|
33
68
|
rescue Logaling::CommandFailed, Logaling::TermError => e
|
|
34
69
|
error(e.message)
|
|
35
70
|
end
|
|
36
71
|
|
|
37
|
-
desc 'delete [
|
|
72
|
+
desc 'delete [SOURCE TERM] [TARGET TERM]', 'Delete term.'
|
|
38
73
|
def delete(source_term, target_term)
|
|
39
|
-
load_config
|
|
40
74
|
glossary.delete(source_term, target_term)
|
|
41
75
|
rescue Logaling::CommandFailed, Logaling::TermError => e
|
|
42
76
|
error(e.message)
|
|
43
77
|
end
|
|
44
78
|
|
|
45
|
-
desc 'update [
|
|
79
|
+
desc 'update [SOURCE TERM] [TARGET TERM] [NEW TARGET TERM], [NOTE(optional)]', 'Update term.'
|
|
46
80
|
def update(source_term, target_term, new_target_term, note='')
|
|
47
|
-
load_config
|
|
48
81
|
glossary.update(source_term, target_term, new_target_term, note)
|
|
49
82
|
rescue Logaling::CommandFailed, Logaling::TermError => e
|
|
50
83
|
error(e.message)
|
|
51
84
|
end
|
|
52
85
|
|
|
53
|
-
desc 'lookup [
|
|
86
|
+
desc 'lookup [TERM]', 'Lookup terms.'
|
|
54
87
|
def lookup(source_term)
|
|
55
|
-
|
|
88
|
+
index
|
|
56
89
|
glossary.lookup(source_term)
|
|
57
90
|
rescue Logaling::CommandFailed, Logaling::TermError => e
|
|
58
91
|
error(e.message)
|
|
@@ -60,30 +93,25 @@ class Logaling::Command < Thor
|
|
|
60
93
|
|
|
61
94
|
desc 'index', 'Index glossaries to groonga DB.'
|
|
62
95
|
def index
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
glossarydb = Logaling::GlossaryDB.new
|
|
67
|
-
glossarydb.open(db_home, "utf8") do |db|
|
|
68
|
-
db.recreate_table(db_home)
|
|
69
|
-
db.load_glossaries(home)
|
|
70
|
-
end
|
|
96
|
+
glossary.index
|
|
97
|
+
rescue Logaling::CommandFailed, Logaling::TermError => e
|
|
98
|
+
error(e.message)
|
|
71
99
|
end
|
|
72
100
|
|
|
73
101
|
private
|
|
74
102
|
def glossary
|
|
75
|
-
|
|
103
|
+
config = load_config
|
|
104
|
+
|
|
105
|
+
glossary = options["glossary"] || config["glossary"]
|
|
76
106
|
raise(Logaling::CommandFailed, "input glossary name '-g <glossary name>'") unless glossary
|
|
77
107
|
|
|
78
|
-
source_language =
|
|
108
|
+
source_language = options["source-language"] || config["source-language"]
|
|
79
109
|
raise(Logaling::CommandFailed, "input source-language code '-S <source-language code>'") unless source_language
|
|
80
110
|
|
|
81
|
-
target_language =
|
|
111
|
+
target_language = options["target-language"] || config["target-language"]
|
|
82
112
|
raise(Logaling::CommandFailed, "input target-language code '-T <target-language code>'") unless target_language
|
|
83
113
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Logaling::Glossary.new(glossary, source_language, target_language, logaling_home)
|
|
114
|
+
Logaling::Glossary.new(glossary, source_language, target_language)
|
|
87
115
|
end
|
|
88
116
|
|
|
89
117
|
def error(msg)
|
|
@@ -91,20 +119,16 @@ class Logaling::Command < Thor
|
|
|
91
119
|
exit 1
|
|
92
120
|
end
|
|
93
121
|
|
|
94
|
-
def find_option(key)
|
|
95
|
-
options[key] || @dot_options[key]
|
|
96
|
-
end
|
|
97
|
-
|
|
98
122
|
def load_config
|
|
99
|
-
|
|
123
|
+
config ||= {}
|
|
100
124
|
if path = find_dotfile
|
|
101
|
-
|
|
102
|
-
tmp_options.each do |option|
|
|
125
|
+
File.readlines(File.join(path, 'config')).map{|l| l.chomp.split " "}.each do |option|
|
|
103
126
|
key = option[0].sub(/^[\-]{2}/, "")
|
|
104
127
|
value = option[1]
|
|
105
|
-
|
|
128
|
+
config[key] = value
|
|
106
129
|
end
|
|
107
130
|
end
|
|
131
|
+
config
|
|
108
132
|
end
|
|
109
133
|
|
|
110
134
|
def find_dotfile
|
data/lib/logaling/glossary.rb
CHANGED
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
#require "logaling-command/version"
|
|
3
|
-
|
|
4
2
|
require 'psych'
|
|
5
3
|
require "yaml"
|
|
6
4
|
require "fileutils"
|
|
5
|
+
require "logaling/glossary_db"
|
|
7
6
|
|
|
8
7
|
module Logaling
|
|
9
8
|
class Glossary
|
|
10
|
-
def self.build_path(glossary, source_language, target_language
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
fname = [glossary, source_language, target_language].join(".")
|
|
14
|
-
return File.join(logaling_home, "#{fname}.yml")
|
|
15
|
-
else
|
|
16
|
-
return glossary
|
|
17
|
-
end
|
|
9
|
+
def self.build_path(glossary, source_language, target_language)
|
|
10
|
+
fname = [glossary, source_language, target_language].join(".")
|
|
11
|
+
File.join(LOGALING_HOME, "projects", glossary, "glossary", "#{fname}.yml")
|
|
18
12
|
end
|
|
19
13
|
|
|
20
|
-
def initialize(glossary, source_language, target_language
|
|
21
|
-
|
|
22
|
-
@path = Glossary.build_path(glossary, source_language, target_language, logaling_home)
|
|
14
|
+
def initialize(glossary, source_language, target_language)
|
|
15
|
+
@path = Glossary.build_path(glossary, source_language, target_language)
|
|
23
16
|
@glossary = glossary
|
|
24
17
|
@source_language = source_language
|
|
25
18
|
@target_language = target_language
|
|
26
|
-
@logaling_home = logaling_home
|
|
27
19
|
end
|
|
28
20
|
|
|
29
21
|
def create
|
|
@@ -81,7 +73,7 @@ module Logaling
|
|
|
81
73
|
check_glossary_exists
|
|
82
74
|
|
|
83
75
|
glossarydb = Logaling::GlossaryDB.new
|
|
84
|
-
glossarydb.open(
|
|
76
|
+
glossarydb.open(File.join(LOGALING_HOME, "db"), "utf8") do |db|
|
|
85
77
|
glossaries = db.lookup(source_term)
|
|
86
78
|
glossaries.reject! do |term|
|
|
87
79
|
term[:source_language] != @source_language || term[:target_language] != @target_language
|
|
@@ -104,13 +96,25 @@ module Logaling
|
|
|
104
96
|
end
|
|
105
97
|
end
|
|
106
98
|
|
|
99
|
+
def index
|
|
100
|
+
projects = Dir.glob(File.join(LOGALING_HOME, "projects", "*"))
|
|
101
|
+
db_home = File.join(LOGALING_HOME, "db")
|
|
102
|
+
glossarydb = Logaling::GlossaryDB.new
|
|
103
|
+
glossarydb.open(db_home, "utf8") do |db|
|
|
104
|
+
db.recreate_table(db_home)
|
|
105
|
+
projects.each do |project|
|
|
106
|
+
db.load_glossaries(File.join(project, "glossary"))
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
107
111
|
private
|
|
108
112
|
def load_glossary_yml
|
|
109
113
|
YAML::load_file(@path) || []
|
|
110
114
|
end
|
|
111
115
|
|
|
112
116
|
def logaling_db_home
|
|
113
|
-
File.join(
|
|
117
|
+
File.join(LOGALING_HOME, "db")
|
|
114
118
|
end
|
|
115
119
|
|
|
116
120
|
def build_term(source_term, target_term, note)
|
|
@@ -134,16 +138,20 @@ module Logaling
|
|
|
134
138
|
target_terms(source_term).any?{|data| data['target_term'] == target_term }
|
|
135
139
|
end
|
|
136
140
|
|
|
137
|
-
def
|
|
138
|
-
File.exists?(@path)
|
|
141
|
+
def check_glossarydir_unexists
|
|
142
|
+
unless File.exists?(File.dirname(@path))
|
|
143
|
+
raise CommandFailed, "glossary path #{File.dirname(@path)} not found"
|
|
144
|
+
end
|
|
139
145
|
end
|
|
140
146
|
|
|
141
147
|
def check_glossary_unexists
|
|
142
|
-
|
|
148
|
+
check_glossarydir_unexists
|
|
149
|
+
raise CommandFailed, "glossary #{@path} already exists" if File.exists?(@path)
|
|
143
150
|
end
|
|
144
151
|
|
|
145
152
|
def check_glossary_exists
|
|
146
|
-
|
|
153
|
+
check_glossarydir_unexists
|
|
154
|
+
FileUtils.touch(@path) unless File.exists?(@path)
|
|
147
155
|
end
|
|
148
156
|
|
|
149
157
|
def target_terms(source_term, path=@path)
|
|
@@ -155,15 +163,6 @@ module Logaling
|
|
|
155
163
|
target_terms
|
|
156
164
|
end
|
|
157
165
|
|
|
158
|
-
def lookup_files
|
|
159
|
-
file_list = Dir.glob("#{@logaling_home}/*.#{@source_language}.#{@target_language}.yml")
|
|
160
|
-
if glossary_index = file_list.index(@path)
|
|
161
|
-
file_list.delete_at(glossary_index)
|
|
162
|
-
end
|
|
163
|
-
file_list.unshift(@path)
|
|
164
|
-
return file_list
|
|
165
|
-
end
|
|
166
|
-
|
|
167
166
|
def dump_glossary(glossary)
|
|
168
167
|
File.open(@path, "w") do |f|
|
|
169
168
|
f.puts(glossary.to_yaml)
|
data/lib/logaling/glossary_db.rb
CHANGED
|
@@ -4,10 +4,11 @@ require 'psych'
|
|
|
4
4
|
require "yaml"
|
|
5
5
|
require "fileutils"
|
|
6
6
|
require 'groonga'
|
|
7
|
+
require 'csv'
|
|
7
8
|
|
|
8
9
|
module Logaling
|
|
9
10
|
class GlossaryDB
|
|
10
|
-
def initialize
|
|
11
|
+
def initialize
|
|
11
12
|
@database = nil
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -46,11 +47,35 @@ module Logaling
|
|
|
46
47
|
@database.nil? or @database.closed?
|
|
47
48
|
end
|
|
48
49
|
|
|
50
|
+
def get_file_list(path, types)
|
|
51
|
+
glob_list = []
|
|
52
|
+
types.each do |type|
|
|
53
|
+
glob_list << File.join(path, "*.#{type}")
|
|
54
|
+
end
|
|
55
|
+
Dir.glob(glob_list)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def load_glossary(file)
|
|
59
|
+
case extname = File.extname(file)
|
|
60
|
+
when ".tsv", ".csv"
|
|
61
|
+
sep = extname == ".tsv" ? "\t" : ","
|
|
62
|
+
glossary = []
|
|
63
|
+
CSV.open(file, "r", {:col_sep => sep}) do |csv|
|
|
64
|
+
csv.each do |row|
|
|
65
|
+
glossary << {"source_term" => row[0], "target_term" => row[1], "note" => ""} if row.size >= 2
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
glossary
|
|
69
|
+
when ".yml"
|
|
70
|
+
YAML::load_file(file)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
49
74
|
def load_glossaries(path)
|
|
50
|
-
file_list =
|
|
75
|
+
file_list = get_file_list(path, ["yml", "tsv", "csv"])
|
|
51
76
|
file_list.each do |file|
|
|
52
|
-
name, source_language, target_language = File::basename(file, "
|
|
53
|
-
glossary =
|
|
77
|
+
name, source_language, target_language = File::basename(file, ".*").split(".")
|
|
78
|
+
glossary = load_glossary(file)
|
|
54
79
|
next if !glossary
|
|
55
80
|
glossary.each do |term|
|
|
56
81
|
source_term = term['source_term']
|
|
@@ -4,18 +4,20 @@ require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
|
|
4
4
|
describe Logaling::Command do
|
|
5
5
|
let(:base_options) { {"glossary"=>"spec", "source-language"=>"en", "target-language"=>"ja"} }
|
|
6
6
|
let(:command) { Logaling::Command.new([], base_options) }
|
|
7
|
-
let(:
|
|
7
|
+
let(:project) { "spec" }
|
|
8
|
+
let(:glossary_path) { Logaling::Glossary.build_path(project, 'en', 'ja') }
|
|
8
9
|
|
|
9
10
|
before do
|
|
10
|
-
FileUtils.
|
|
11
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
|
12
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
describe '#create' do
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end
|
|
16
|
+
before do
|
|
17
|
+
FileUtils.touch(glossary_path)
|
|
18
|
+
end
|
|
18
19
|
|
|
20
|
+
context 'with arguments show non-existent glossary' do
|
|
19
21
|
it "glossary yaml should be newly created" do
|
|
20
22
|
File.exists?(glossary_path).should be_true
|
|
21
23
|
end
|
|
@@ -23,10 +25,6 @@ describe Logaling::Command do
|
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
describe '#add' do
|
|
26
|
-
before do
|
|
27
|
-
command.create
|
|
28
|
-
end
|
|
29
|
-
|
|
30
28
|
context 'with arguments have only bilingual pair' do
|
|
31
29
|
before do
|
|
32
30
|
command.add("spec", "テスト")
|
|
@@ -41,7 +39,7 @@ describe Logaling::Command do
|
|
|
41
39
|
it "term should note have note" do
|
|
42
40
|
subject["note"].should == ""
|
|
43
41
|
end
|
|
44
|
-
|
|
42
|
+
end
|
|
45
43
|
|
|
46
44
|
context 'with arguments have bilingual pair and note' do
|
|
47
45
|
before do
|
|
@@ -62,7 +60,6 @@ describe Logaling::Command do
|
|
|
62
60
|
|
|
63
61
|
describe "#update" do
|
|
64
62
|
before do
|
|
65
|
-
command.create
|
|
66
63
|
command.add("spec", "テスト", "備考")
|
|
67
64
|
end
|
|
68
65
|
|
|
@@ -95,7 +92,62 @@ describe Logaling::Command do
|
|
|
95
92
|
end
|
|
96
93
|
end
|
|
97
94
|
|
|
95
|
+
describe '#index' do
|
|
96
|
+
before do
|
|
97
|
+
command.add("spec", "スペック", "備考")
|
|
98
|
+
command.index
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context 'glossary files exist in some project' do
|
|
102
|
+
db_home = File.join(LOGALING_HOME, "db")
|
|
103
|
+
db = Logaling::GlossaryDB.new
|
|
104
|
+
|
|
105
|
+
subject { db.open(db_home, "utf8"){|db| records = db.lookup("spec")} }
|
|
106
|
+
|
|
107
|
+
it 'glossaries should be indexed' do
|
|
108
|
+
subject.should == [{:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"spec", :target_term=>"スペック", :note=>"備考"}]
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe '#lookup' do
|
|
114
|
+
let(:base_options2) { {"glossary"=>"spec2", "source-language"=>"en", "target-language"=>"ja"} }
|
|
115
|
+
let(:command2) { Logaling::Command.new([], base_options2) }
|
|
116
|
+
let(:project2) { "spec2" }
|
|
117
|
+
let(:glossary_path2) { Logaling::Glossary.build_path(project2, 'en', 'ja') }
|
|
118
|
+
|
|
119
|
+
context 'with arguments exist term' do
|
|
120
|
+
before do
|
|
121
|
+
command.add("spec", "スペック", "備考")
|
|
122
|
+
FileUtils.mkdir_p(File.dirname(glossary_path2))
|
|
123
|
+
command2.add("spec", "スペック")
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'succeed at find by term without command.index' do
|
|
127
|
+
stdout = capture(:stdout) {command.lookup("spec")}
|
|
128
|
+
stdout.should == <<-EOM
|
|
129
|
+
|
|
130
|
+
lookup word : spec
|
|
131
|
+
|
|
132
|
+
spec
|
|
133
|
+
スペック
|
|
134
|
+
note:備考
|
|
135
|
+
glossary:spec
|
|
136
|
+
|
|
137
|
+
spec
|
|
138
|
+
スペック
|
|
139
|
+
note:
|
|
140
|
+
glossary:spec2
|
|
141
|
+
EOM
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
after do
|
|
145
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec2'), true)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
98
150
|
after do
|
|
99
|
-
FileUtils.
|
|
151
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
|
100
152
|
end
|
|
101
153
|
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper")
|
|
3
|
+
|
|
4
|
+
describe Logaling::GlossaryDB do
|
|
5
|
+
let(:glossary_path) { Logaling::Glossary.build_path('spec', 'en', 'ja') }
|
|
6
|
+
let(:tsv_path) { File.join(File.dirname(glossary_path), 'spec.en.ja.tsv') }
|
|
7
|
+
let(:csv_path) { File.join(File.dirname(glossary_path), 'spec.en.ja.csv') }
|
|
8
|
+
let(:glossary_db) { Logaling::GlossaryDB.new }
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
|
12
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe '#get_file_list' do
|
|
16
|
+
context 'when specified file not exist' do
|
|
17
|
+
subject { glossary_db.get_file_list(File.dirname(glossary_path), ['yml', 'csv', 'tsv']) }
|
|
18
|
+
it 'should return empty array' do
|
|
19
|
+
should == []
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'when specified file exists' do
|
|
24
|
+
before do
|
|
25
|
+
FileUtils.touch(glossary_path)
|
|
26
|
+
FileUtils.touch(tsv_path)
|
|
27
|
+
FileUtils.touch(csv_path)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
subject { glossary_db.get_file_list(File.dirname(glossary_path), ['yml', 'csv', 'tsv']) }
|
|
31
|
+
it 'should return file list' do
|
|
32
|
+
should == [glossary_path, csv_path, tsv_path]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
after do
|
|
36
|
+
FileUtils.remove_entry_secure(glossary_path, true)
|
|
37
|
+
FileUtils.remove_entry_secure(tsv_path, true)
|
|
38
|
+
FileUtils.remove_entry_secure(csv_path, true)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe '#load_glossary' do
|
|
44
|
+
context 'with argument yml' do
|
|
45
|
+
before do
|
|
46
|
+
FileUtils.touch(glossary_path)
|
|
47
|
+
term = [{'source_term' => 'spec', 'target_term' => 'スペック', 'note' => 'スペック'}]
|
|
48
|
+
File.open(glossary_path, "w"){|f| f.puts(term.to_yaml)}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
subject { glossary_db.load_glossary(glossary_path) }
|
|
52
|
+
|
|
53
|
+
it 'should return formatted glossary' do
|
|
54
|
+
should == [{'source_term' => 'spec', 'target_term' => 'スペック', 'note' => 'スペック'}]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
after do
|
|
58
|
+
FileUtils.remove_entry_secure(glossary_path, true)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'with argument tsv' do
|
|
63
|
+
before do
|
|
64
|
+
FileUtils.touch(tsv_path)
|
|
65
|
+
term = "spec\tスペック"
|
|
66
|
+
File.open(tsv_path, "w"){|f| f.puts(term)}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
subject { glossary_db.load_glossary(tsv_path) }
|
|
70
|
+
|
|
71
|
+
it 'should return formatted glossary' do
|
|
72
|
+
should == [{'source_term' => 'spec', 'target_term' => 'スペック', 'note' => ''}]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
after do
|
|
76
|
+
FileUtils.remove_entry_secure(tsv_path, true)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context 'with argument csv' do
|
|
81
|
+
before do
|
|
82
|
+
FileUtils.touch(csv_path)
|
|
83
|
+
term = "spec,スペック,備考\ntest\n"
|
|
84
|
+
File.open(csv_path, "w"){|f| f.puts(term)}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
subject { glossary_db.load_glossary(csv_path) }
|
|
88
|
+
|
|
89
|
+
it 'should return formatted glossary' do
|
|
90
|
+
should == [{'source_term' => 'spec', 'target_term' => 'スペック', 'note' => ''}]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
after do
|
|
94
|
+
FileUtils.remove_entry_secure(csv_path, true)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
after do
|
|
100
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
@@ -4,15 +4,39 @@ require "fileutils"
|
|
|
4
4
|
|
|
5
5
|
module Logaling
|
|
6
6
|
describe Glossary do
|
|
7
|
-
let(:
|
|
8
|
-
let(:
|
|
7
|
+
let(:project) { "spec" }
|
|
8
|
+
let(:glossary) { Glossary.new(project, 'en', 'ja') }
|
|
9
|
+
let(:glossary_path) { Glossary.build_path(project, 'en', 'ja') }
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
before do
|
|
12
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
|
13
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '#create' do
|
|
17
|
+
context 'when glossary already exists' do
|
|
18
|
+
before do
|
|
19
|
+
FileUtils.touch(glossary_path)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it {
|
|
23
|
+
-> { glossary.create }.should raise_error(Logaling::CommandFailed)
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'newly create' do
|
|
28
|
+
before do
|
|
29
|
+
glossary.create
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# <glossary name>.source-language.target_language.yml というファイル名で用語集が作成されること
|
|
33
|
+
it 'specified glossary should has created' do
|
|
34
|
+
File.exists?(glossary_path).should be_true
|
|
35
|
+
end
|
|
14
36
|
end
|
|
37
|
+
end
|
|
15
38
|
|
|
39
|
+
describe '#add' do
|
|
16
40
|
context 'with arguments show new bilingual pair' do
|
|
17
41
|
before do
|
|
18
42
|
glossary.add("spec", "スペック", "テストスペック")
|
|
@@ -35,15 +59,31 @@ module Logaling
|
|
|
35
59
|
}
|
|
36
60
|
end
|
|
37
61
|
|
|
38
|
-
|
|
39
|
-
|
|
62
|
+
context "when the glossary not found" do
|
|
63
|
+
before do
|
|
64
|
+
glossary.add("test", "テスト", "テスト")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should create the glossary and add term" do
|
|
68
|
+
yaml = YAML::load_file(glossary_path)
|
|
69
|
+
term = yaml.index({"source_term"=>"test", "target_term"=>"テスト", "note"=>"テスト"})
|
|
70
|
+
term.should_not be_nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context "when the glossary dir not found" do
|
|
75
|
+
before do
|
|
76
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it {
|
|
80
|
+
-> { glossary.add("test", "テスト", "テスト") }.should raise_error(Logaling::CommandFailed)
|
|
81
|
+
}
|
|
40
82
|
end
|
|
41
83
|
end
|
|
42
84
|
|
|
43
85
|
describe '#update' do
|
|
44
86
|
before do
|
|
45
|
-
FileUtils.remove_file(glossary_path, true)
|
|
46
|
-
glossary.create
|
|
47
87
|
glossary.add("user", "ユーザ", "ユーザーではない")
|
|
48
88
|
end
|
|
49
89
|
|
|
@@ -64,16 +104,10 @@ module Logaling
|
|
|
64
104
|
-> { glossary.update("user", "ユー", "ユーザー", "やっぱりユーザー") }.should raise_error(Logaling::TermError)
|
|
65
105
|
}
|
|
66
106
|
end
|
|
67
|
-
|
|
68
|
-
after do
|
|
69
|
-
FileUtils.remove_file(glossary_path, true)
|
|
70
|
-
end
|
|
71
107
|
end
|
|
72
108
|
|
|
73
109
|
describe '#delete' do
|
|
74
110
|
before do
|
|
75
|
-
FileUtils.remove_file(glossary_path, true)
|
|
76
|
-
glossary.create
|
|
77
111
|
glossary.add("user", "ユーザ", "ユーザーではない")
|
|
78
112
|
end
|
|
79
113
|
|
|
@@ -82,35 +116,130 @@ module Logaling
|
|
|
82
116
|
-> { glossary.delete("user", "ユーザー") }.should raise_error(Logaling::TermError)
|
|
83
117
|
}
|
|
84
118
|
end
|
|
85
|
-
|
|
86
|
-
after do
|
|
87
|
-
FileUtils.remove_file(glossary_path, true)
|
|
88
|
-
end
|
|
89
119
|
end
|
|
90
120
|
|
|
91
121
|
describe '#lookup' do
|
|
92
122
|
before do
|
|
93
|
-
FileUtils.remove_file(glossary_path, true)
|
|
94
|
-
glossary.create
|
|
95
123
|
glossary.add("user", "ユーザ", "ユーザーではない")
|
|
124
|
+
end
|
|
96
125
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
126
|
+
context 'with arguments show existing bilingual pair' do
|
|
127
|
+
it 'succeed at find by term' do
|
|
128
|
+
glossary.index
|
|
129
|
+
stdout = capture(:stdout) {glossary.lookup("user")}
|
|
130
|
+
stdout.should == <<-EOM
|
|
131
|
+
|
|
132
|
+
lookup word : user
|
|
133
|
+
|
|
134
|
+
user
|
|
135
|
+
ユーザ
|
|
136
|
+
note:ユーザーではない
|
|
137
|
+
glossary:spec
|
|
138
|
+
EOM
|
|
102
139
|
end
|
|
103
140
|
end
|
|
104
141
|
|
|
105
|
-
context '
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
142
|
+
context 'when tsv file as glossary exists' do
|
|
143
|
+
let(:tsv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.tsv") }
|
|
144
|
+
|
|
145
|
+
before do
|
|
146
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
|
147
|
+
FileUtils.touch(tsv_path)
|
|
148
|
+
File.open(tsv_path, "w"){|f| f.puts "user\tユーザー"}
|
|
149
|
+
glossary.index
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'succeed at find by term' do
|
|
153
|
+
glossary.index
|
|
154
|
+
stdout = capture(:stdout) {glossary.lookup("user")}
|
|
155
|
+
stdout.should == <<-EOM
|
|
156
|
+
|
|
157
|
+
lookup word : user
|
|
158
|
+
|
|
159
|
+
user
|
|
160
|
+
ユーザ
|
|
161
|
+
note:ユーザーではない
|
|
162
|
+
glossary:spec
|
|
163
|
+
|
|
164
|
+
user
|
|
165
|
+
ユーザー
|
|
166
|
+
note:
|
|
167
|
+
glossary:spec
|
|
168
|
+
EOM
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
after do
|
|
172
|
+
FileUtils.remove_entry_secure(tsv_path, true)
|
|
173
|
+
end
|
|
109
174
|
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe '#index' do
|
|
178
|
+
let(:db_home) { File.join(LOGALING_HOME, "db") }
|
|
179
|
+
let(:logaling_db) { Logaling::GlossaryDB.new }
|
|
180
|
+
let(:tsv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.tsv") }
|
|
181
|
+
let(:csv_path) { File.join(File.dirname(glossary_path), "spec.en.ja.csv") }
|
|
182
|
+
|
|
183
|
+
context 'when yml file as glossary exists' do
|
|
184
|
+
before do
|
|
185
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
|
186
|
+
FileUtils.touch(glossary_path)
|
|
187
|
+
glossary.add("spec", "スペック", "備考")
|
|
188
|
+
glossary.index
|
|
189
|
+
end
|
|
110
190
|
|
|
111
|
-
|
|
112
|
-
|
|
191
|
+
subject { logaling_db.open(db_home, "utf8"){|db| logaling_db.lookup("spec")} }
|
|
192
|
+
|
|
193
|
+
it 'glossaries should be indexed' do
|
|
194
|
+
subject.should == [{:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"spec", :target_term=>"スペック", :note=>"備考"}]
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
after do
|
|
198
|
+
FileUtils.remove_entry_secure(glossary_path, true)
|
|
199
|
+
end
|
|
113
200
|
end
|
|
201
|
+
|
|
202
|
+
context 'when tsv file as glossary exists' do
|
|
203
|
+
before do
|
|
204
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
|
205
|
+
FileUtils.touch(tsv_path)
|
|
206
|
+
File.open(tsv_path, "w"){|f| f.puts "user\tユーザ"}
|
|
207
|
+
glossary.index
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
subject { logaling_db.open(db_home, "utf8"){|db| logaling_db.lookup("user")} }
|
|
211
|
+
|
|
212
|
+
it 'glossaries should be indexed' do
|
|
213
|
+
subject.should == [{:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"user", :target_term=>"ユーザ", :note=>nil}]
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
after do
|
|
217
|
+
FileUtils.remove_entry_secure(tsv_path, true)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
context 'when csv file as glosary exists' do
|
|
222
|
+
before do
|
|
223
|
+
FileUtils.mkdir_p(File.dirname(glossary_path))
|
|
224
|
+
FileUtils.touch(csv_path)
|
|
225
|
+
File.open(csv_path, "w"){|f| f.puts "test,テスト"}
|
|
226
|
+
glossary.index
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
subject { logaling_db.open(db_home, "utf8"){|db| logaling_db.lookup("test")} }
|
|
230
|
+
|
|
231
|
+
it 'glossaries should be indexed' do
|
|
232
|
+
subject.should == [{:name=>"spec", :source_language=>"en", :target_language=>"ja", :source_term=>"test", :target_term=>"テスト", :note=>nil}]
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
after do
|
|
236
|
+
FileUtils.remove_entry_secure(csv_path, true)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
after do
|
|
242
|
+
FileUtils.remove_entry_secure(File.join(LOGALING_HOME, 'projects', 'spec'), true)
|
|
114
243
|
end
|
|
115
244
|
end
|
|
116
245
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logaling-command
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -13,11 +13,11 @@ authors:
|
|
|
13
13
|
autorequire:
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
|
-
date: 2011-11-
|
|
16
|
+
date: 2011-11-22 00:00:00.000000000Z
|
|
17
17
|
dependencies:
|
|
18
18
|
- !ruby/object:Gem::Dependency
|
|
19
19
|
name: thor
|
|
20
|
-
requirement: &
|
|
20
|
+
requirement: &2154516840 !ruby/object:Gem::Requirement
|
|
21
21
|
none: false
|
|
22
22
|
requirements:
|
|
23
23
|
- - ! '>='
|
|
@@ -25,10 +25,10 @@ dependencies:
|
|
|
25
25
|
version: 0.14.6
|
|
26
26
|
type: :runtime
|
|
27
27
|
prerelease: false
|
|
28
|
-
version_requirements: *
|
|
28
|
+
version_requirements: *2154516840
|
|
29
29
|
- !ruby/object:Gem::Dependency
|
|
30
30
|
name: bundler
|
|
31
|
-
requirement: &
|
|
31
|
+
requirement: &2154515940 !ruby/object:Gem::Requirement
|
|
32
32
|
none: false
|
|
33
33
|
requirements:
|
|
34
34
|
- - ! '>='
|
|
@@ -36,10 +36,10 @@ dependencies:
|
|
|
36
36
|
version: '1.0'
|
|
37
37
|
type: :runtime
|
|
38
38
|
prerelease: false
|
|
39
|
-
version_requirements: *
|
|
39
|
+
version_requirements: *2154515940
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: rake
|
|
42
|
-
requirement: &
|
|
42
|
+
requirement: &2154515340 !ruby/object:Gem::Requirement
|
|
43
43
|
none: false
|
|
44
44
|
requirements:
|
|
45
45
|
- - ! '>='
|
|
@@ -47,10 +47,10 @@ dependencies:
|
|
|
47
47
|
version: '0'
|
|
48
48
|
type: :development
|
|
49
49
|
prerelease: false
|
|
50
|
-
version_requirements: *
|
|
50
|
+
version_requirements: *2154515340
|
|
51
51
|
- !ruby/object:Gem::Dependency
|
|
52
52
|
name: rspec
|
|
53
|
-
requirement: &
|
|
53
|
+
requirement: &2154514760 !ruby/object:Gem::Requirement
|
|
54
54
|
none: false
|
|
55
55
|
requirements:
|
|
56
56
|
- - ! '>='
|
|
@@ -58,7 +58,7 @@ dependencies:
|
|
|
58
58
|
version: '0'
|
|
59
59
|
type: :development
|
|
60
60
|
prerelease: false
|
|
61
|
-
version_requirements: *
|
|
61
|
+
version_requirements: *2154514760
|
|
62
62
|
description: A command line interface for logaling.
|
|
63
63
|
email:
|
|
64
64
|
- koji.shimada@enishi-tech.com
|
|
@@ -82,6 +82,7 @@ files:
|
|
|
82
82
|
- lib/logaling/glossary_db.rb
|
|
83
83
|
- logaling-command.gemspec
|
|
84
84
|
- spec/logaling/command_spec.rb
|
|
85
|
+
- spec/logaling/glossary_db_spec.rb
|
|
85
86
|
- spec/logaling/glossary_spec.rb
|
|
86
87
|
- spec/spec_helper.rb
|
|
87
88
|
homepage: http://logaling.github.com/
|
|
@@ -110,5 +111,6 @@ specification_version: 3
|
|
|
110
111
|
summary: A command line interface for logaling.
|
|
111
112
|
test_files:
|
|
112
113
|
- spec/logaling/command_spec.rb
|
|
114
|
+
- spec/logaling/glossary_db_spec.rb
|
|
113
115
|
- spec/logaling/glossary_spec.rb
|
|
114
116
|
- spec/spec_helper.rb
|