noir 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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