noir 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e0a981055827741b98263f272970c2a76ba53c2b
4
- data.tar.gz: 42e09ce72746a6b8381f36bfc687cbd86a4aa19e
3
+ metadata.gz: 321b15d42d793bbc446da53068990490c43d1d53
4
+ data.tar.gz: 958e080bde8a7e4aba828cef99ad0587b774b869
5
5
  SHA512:
6
- metadata.gz: 3ea4f8bd2daabba6eecde179adae24beeb81c83ce77a6b0e5df53ba2484bcc900e61d0ac05a62dde9750073994d572491397c6babf317687762874d9d8cbe0a8
7
- data.tar.gz: 5413ee5c9777dd811391a4b64a959e18b9967e512a534b4dfcfe8ecd0a1f38d46d1a2fbe46f30c114be9020857ce39d25f1f0af2e20e2f124f0b8869fc371c57
6
+ metadata.gz: 047e554c78f92f237badf491e967d86c8a8af8edb89938f0cc9350dc1c39376f2e7d841dd6481fb648aee8107ba65f10b0c7ac6b823bbcd3e9c54e99d34477ee
7
+ data.tar.gz: fc30d7f7a8890a13a01fafeca7ec82e1a8984b044224c83cb003ce86136008ac9ecec46833e8898c4540574186be68eb8bb54a23f153ce286fdac7747e5bde85
@@ -1,33 +1,52 @@
1
1
  module Noir
2
2
  class Executer
3
3
 
4
+ # utils
5
+
6
+ def self.find_command command_arr, search_str
7
+ command = eval(command_arr.join('::'))
8
+
9
+ # finish find by terminal command
10
+ return nil if command.superclass == Noir::Base::TerminalCommand
11
+
12
+ commands = command.constants(true).map(&:to_s)
13
+ matched_str = commands.find{|c| c.downcase == search_str.downcase}
14
+ matched_str = find_abbr_command(commands, search_str) if matched_str.nil?
15
+
16
+ return nil if matched_str.nil?
17
+ matched_arr = command_arr + [matched_str]
18
+ unless eval(matched_arr.join('::')).ancestors.include?(Noir::Base::Command)
19
+ # matched. but matched class is not inherited commmand
20
+ return nil
21
+ end
22
+
23
+ return matched_str
24
+ end
25
+
26
+ def self.find_abbr_command commands, search_str
27
+ # abbrev match
28
+ matched_commands = commands.select{|c| c.downcase.start_with? search_str}
29
+
30
+ return nil if matched_commands.empty?
31
+ unless matched_commands.size == 1
32
+ raise "#{search_str} is ambiguous. matched #{matched_commands}"
33
+ end
34
+
35
+ matched_commands.first
36
+ end
37
+
4
38
  def self.command_from_argv
5
39
  args = ARGV.clone
6
- noir_commands = Noir::Command.constants(true).map(&:to_s)
7
- command_arr = ['Noir', 'Command'] # command prefix
8
-
9
-
10
- while !args.empty?
11
- arg = args.shift
12
-
13
- if matched_command = noir_commands.find{|c| c.downcase == arg.downcase}
14
-
15
- command_arr << matched_command
16
- command = eval(command_arr.join('::'))
17
- if command.superclass == Noir::Base::Command
18
- noir_commands = command.constants(true).map(&:to_s) # search next command in sub class
19
- elsif command.superclass == Noir::Base::TerminalCommand
20
- break # search finished by terminal command
21
- else
22
- command_arr.pop
23
- # delete last matched_command, because this class is not inherited Noir::Base::Command
24
- command = eval(command_arr.join('::'))
25
- break
26
- end
27
- end
40
+ command_arr = ['Noir', 'Command'] # command prefix and default command
41
+
42
+ while true
43
+ break unless search_str = args.shift
44
+ break unless matched_command = find_command(command_arr, search_str)
45
+
46
+ command_arr << matched_command
28
47
  end
29
48
 
30
- return command || Noir::Command # default command
49
+ return eval(command_arr.join('::'))
31
50
  end
32
51
 
33
52
  def self.args_from_argv
@@ -38,6 +57,8 @@ module Noir
38
57
  return argv.drop(command_size)
39
58
  end
40
59
 
60
+ # inherited methods
61
+
41
62
  def self.execute
42
63
  command_from_argv.execute *args_from_argv
43
64
  end
@@ -1,3 +1,3 @@
1
1
  module Noir
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -14,6 +14,7 @@ describe 'Noir::Command::Completion' do
14
14
  it 'return all command from nil' do
15
15
  expect(Noir::Command::Completion.suggestions([])).to include('hoge')
16
16
  expect(Noir::Command::Completion.suggestions([])).to include('fuga')
17
+ expect(Noir::Command::Completion.suggestions([])).to include('fugafuga')
17
18
  end
18
19
 
19
20
  it 'return nil from unmatched pattern' do
@@ -24,6 +25,7 @@ describe 'Noir::Command::Completion' do
24
25
  list = ['h']
25
26
  expect(Noir::Command::Completion.suggestions(list)).to include('hoge')
26
27
  expect(Noir::Command::Completion.suggestions(list)).to_not include('fuga')
28
+ expect(Noir::Command::Completion.suggestions(list)).to_not include('fugafuga')
27
29
  end
28
30
 
29
31
  it 'return command list in sub command' do
@@ -23,15 +23,21 @@ describe 'Noir::Executer' do
23
23
  it 'return Noir::Command' do
24
24
  expect(Noir::Executer.command_from_argv).to eq(Noir::Command)
25
25
  end
26
- end
26
+ end # in undefined ARGV
27
27
 
28
- describe 'in defined argv' do
28
+ describe 'in defined ARGV' do
29
29
 
30
30
  it 'return command' do
31
31
  stub_const 'ARGV', ['hoge']
32
32
  expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
33
33
  end
34
34
 
35
+ it 'return prefix duplicated command' do
36
+ stub_const 'ARGV', ['fuga']
37
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Fuga)
38
+ expect(Noir::Executer.command_from_argv).not_to eq(Noir::Command::FugaFuga)
39
+ end
40
+
35
41
  it 'return command if has other arguments' do
36
42
  stub_const 'ARGV', ['hoge', 'aaa']
37
43
  expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
@@ -77,8 +83,41 @@ describe 'Noir::Executer' do
77
83
  expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Fuga)
78
84
  end
79
85
 
86
+ describe 'abbrev command' do
87
+
88
+ it 'return only matched command' do
89
+ stub_const 'ARGV', ['ho']
90
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
91
+ end
92
+
93
+ it 'raise exception matched one more' do
94
+ stub_const 'ARGV', ['h']
95
+ expect{Noir::Executer.command_from_argv}.to raise_error
96
+ end
97
+
98
+ it 'support multi command abbrev' do
99
+ stub_const 'ARGV', ['ho', 'subcommandt']
100
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommandTwo)
101
+ end
102
+
103
+ it 'support multi command abbrev with args' do
104
+ stub_const 'ARGV', ['ho', 'subcommandt', 'piyo']
105
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommandTwo)
106
+ end
107
+
108
+ end
109
+ end # in defined ARGV
110
+ end # command_from_argv
111
+
112
+ describe 'find_command' do
113
+ it 'return perfect matched command' do
114
+ expect(Noir::Executer.find_command ['Noir', 'Command'], 'hoge').to eq('Hoge')
80
115
  end
81
- end
116
+
117
+ it 'raise exeption in ambiguous match' do
118
+ expect{Noir::Executer.find_command(['Noir', 'Command'], 'f')}.to raise_error
119
+ end
120
+ end # find_command
82
121
 
83
122
  describe 'args_from_argv' do
84
123
 
@@ -88,9 +127,9 @@ describe 'Noir::Executer' do
88
127
  it 'return []' do
89
128
  expect(Noir::Executer.args_from_argv).to eq([])
90
129
  end
91
- end
130
+ end # in undefined ARGV
92
131
 
93
- describe 'in defined argv' do
132
+ describe 'in defined ARGV' do
94
133
 
95
134
  it 'return [] if only command' do
96
135
  stub_const 'ARGV', ['hoge']
@@ -162,6 +201,7 @@ describe 'Noir::Executer' do
162
201
  expect(Noir::Executer.args_from_argv).to eq(['aaa', 'bbb'])
163
202
  end
164
203
 
165
- end
166
- end
204
+ end # in defined argv
205
+
206
+ end # args_from_argv
167
207
  end
@@ -12,26 +12,30 @@ def stub_commands
12
12
  stub_const('Noir::Command::Hoge::SubCommandTwo' , Class.new(Noir::Base::Command))
13
13
  stub_const('Noir::Command::Hoge::SubNonCommand' , Class.new)
14
14
  stub_const('Noir::Command::Fuga' , Class.new(Noir::Base::TerminalCommand))
15
+ stub_const('Noir::Command::FugaFuga' , Class.new(Noir::Base::TerminalCommand))
15
16
 
17
+ # stub_const is this structure
16
18
  =begin
17
- # stub_const is this structure
18
- module Noir::Command
19
- class Hoge < Noir::Base::Command
20
- class SubCommand < Noir::Base::Command
21
- class SubSubCommand < Noir::Base::Command
22
- end
23
- class SubSubNonCommand
24
- end
25
- end
26
- class SubCommandTwo < Noir::Base::Command
27
- end
28
-
29
- class SubNonCommand
30
- end
19
+ class Noir::Command
20
+ class Hoge < Noir::Base::Command
21
+ class SubCommand < Noir::Base::Command
22
+ class SubSubCommand < Noir::Base::Command
31
23
  end
32
- class Fuga < Noir::Base::TerminalCommand
24
+ class SubSubNonCommand
33
25
  end
34
26
  end
27
+
28
+ class SubCommandTwo < Noir::Base::Command
29
+ end
30
+
31
+ class SubNonCommand
32
+ end
33
+ end
34
+ class Fuga < Noir::Base::TerminalCommand
35
+ end
36
+ class Fuga < Noir::Base::TerminalCommand
37
+ end
38
+ end
35
39
  =end
36
40
 
37
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noir
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - atton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-09 00:00:00.000000000 Z
11
+ date: 2014-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler