noir 0.0.1

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: ba0f4b6e225d9fd7b76ac11a2880ea68e6f07f63
4
+ data.tar.gz: a9f636f6d453963747b276222fb16c35a1589b6a
5
+ SHA512:
6
+ metadata.gz: 4d80e2b8ba59dde0ce9e726368f5123ae5ca0c836fb0e3cc0649dac7db1699dcb3e46ff276417aa23416707d923fedccdba7661a58a7e0510bc8df9029f4341d
7
+ data.tar.gz: 09fd81daeaa775c0a75a8742fac986047cfd084df5a77e67e495106ac049f1155f232bb872ba582048735fdfd3524d4f9fee82c99abb06f11d857827cfc654c6
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in iris.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 atton
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # Noir
2
+
3
+ Noir is utility commands for atton.
4
+
5
+
6
+ ## Installation
7
+
8
+ $ gem install noir
9
+
10
+ ## Usage
11
+
12
+ $ noir <command> [sub-command...] [args-for-command]
13
+
14
+ ## Enable Completion
15
+
16
+ Add this code in .zshrc
17
+
18
+ ``` if which noir >& /dev/null; then eval "$(noir init zsh)"; fi ```
19
+
20
+ ## Contributing
21
+
22
+ 1. Fork it ( http://github.com/atton-/noir/fork )
23
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
24
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
25
+ 4. Push to the branch (`git push origin my-new-feature`)
26
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/noir ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'noir'
3
+
4
+ begin
5
+ Noir.main
6
+ rescue => e
7
+ puts e.message
8
+ end
data/lib/noir.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'noir/version'
2
+ require 'noir/options'
3
+ require 'noir/executer'
4
+ require 'noir/base'
5
+ require 'noir/base/terminal_command'
6
+ require 'noir/command'
7
+
8
+ module Noir
9
+ def self.main
10
+ Noir::Options.parse_options_from_argv!
11
+ Noir::Executer.execute
12
+ end
13
+ end
data/lib/noir/base.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'noir/base/command'
2
+ require 'noir/base/terminal_command'
3
+
4
+ module Noir
5
+ module Base
6
+ end
7
+ end
@@ -0,0 +1,41 @@
1
+ module Noir::Base
2
+
3
+ class Command
4
+
5
+ class << self # class methods
6
+ def description
7
+ if @description.nil?
8
+ raise "Undefined description : " + self.to_s
9
+ else
10
+ puts self.to_s.split(':').last.downcase.ljust(15) + " : " + @description
11
+ end
12
+ end
13
+
14
+ def execute *args
15
+ if self == Noir::Base::Command
16
+ raise 'called raw Noir::Base::Command.execute. please call it in extended class.'
17
+ end
18
+
19
+ # check invalid command
20
+ check_command_not_found *args
21
+
22
+ # default execute is show description with sub commands.
23
+ description
24
+ puts '-- sub commands --'
25
+ sub_commands.map{|c|eval(self.to_s + '::' + c.to_s)}.each{|c| c.description}
26
+ end
27
+
28
+ def sub_commands
29
+ consts = constants - superclass.constants
30
+ consts = consts.select{|c| const_get(c).ancestors.include?(Noir::Base::Command)}
31
+ end
32
+
33
+ def check_command_not_found command=nil, *args
34
+ return if command.nil?
35
+
36
+ raise 'command not found : ' + command
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ module Noir::Base
2
+ class TerminalCommand < Noir::Base::Command
3
+
4
+ class << self
5
+
6
+ def execute *args
7
+ if self == Noir::Base::TerminalCommand
8
+ raise 'called raw Noir::Base::TerminalCommand.execute. please call it in extended class.'
9
+ end
10
+
11
+ raise 'please override in extended class'
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ class Noir::Command < Noir::Base::Command
2
+ class << self
3
+ def execute *args
4
+ # if arguments missing. call help.
5
+ Noir::Command::Help.execute if args.size.zero?
6
+ check_command_not_found *args
7
+ end
8
+ end
9
+ end
10
+
11
+ require 'noir/command/init'
12
+ require 'noir/command/completion'
13
+ require 'noir/command/help'
14
+ require 'noir/command/new'
@@ -0,0 +1,51 @@
1
+ class Noir::Command::Completion < Noir::Base::TerminalCommand
2
+
3
+ @description = 'it is completion for shell. return command suggestion'
4
+
5
+ class << self
6
+
7
+ def execute *args
8
+ if Noir::Options.exist? Noir::Options::Help
9
+ description
10
+ exit
11
+ end
12
+ puts suggestions(args)
13
+ end
14
+
15
+ def suggestions list
16
+ if list.size.zero?
17
+ return suggestions_from_command Noir::Command, nil
18
+ end
19
+
20
+ commands = [:Noir, :Command] + list
21
+
22
+ matched_commands = [commands.first]
23
+ commands = commands.drop(1)
24
+
25
+ while true
26
+ consts = eval(matched_commands.map(&:to_s).join('::')).constants(true)
27
+
28
+ break if commands.size.zero?
29
+ matched_command = consts.find{|c| c.to_s.downcase == commands.first.to_s.downcase}
30
+ break if matched_command.nil?
31
+
32
+ matched_commands << matched_command
33
+ commands = commands.drop(1)
34
+ end
35
+
36
+ command_class = eval(matched_commands.map(&:to_s).join('::'))
37
+ suggestions_from_command(command_class, commands.first)
38
+ end
39
+
40
+ def suggestions_from_command klass, pattern = nil
41
+ suggests = klass.constants(true).map(&:to_s).map(&:downcase)
42
+
43
+ unless pattern.nil?
44
+ suggests = suggests.select{|c| c.start_with? pattern.downcase}
45
+ end
46
+
47
+ return suggests
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,19 @@
1
+ class Noir::Command::Help < Noir::Base::TerminalCommand
2
+
3
+ @description = "show help"
4
+
5
+ class << self
6
+ def execute *args
7
+ check_command_not_found *args
8
+
9
+ puts 'noir : utilities'
10
+ puts '-----'
11
+
12
+ Noir::Command.constants(true).
13
+ map{|c| eval('Noir::Command::'+c.to_s)}.
14
+ select{|c| c.ancestors.include? Noir::Base::Command}.
15
+ each(&:description)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,5 @@
1
+ class Noir::Command::Init < Noir::Base::Command
2
+ @description = "init script for shell"
3
+ end
4
+
5
+ require 'noir/command/init/zsh'
@@ -0,0 +1,33 @@
1
+ class Noir::Command::Init::Zsh < Noir::Base::TerminalCommand
2
+ @description = "init script for zsh"
3
+
4
+ # enable completion for zsh
5
+ # wrote this code in .zshrc
6
+ # if which noir >& /dev/null; then eval "$(noir init zsh)"; fi
7
+
8
+ InitScript = %q(
9
+
10
+ if [[ ! -o interactive ]]; then
11
+ return
12
+ fi
13
+
14
+ compctl -K _noir noir
15
+
16
+ _noir() {
17
+ local words completions
18
+ read -cA words
19
+
20
+ completions="$(noir completion ${words[2,-2]})"
21
+
22
+ reply=("${(ps:\n:)completions}")
23
+ }
24
+
25
+ )
26
+ class << self
27
+
28
+ def execute *args
29
+ puts InitScript
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ class Noir::Command::New < Noir::Base::Command
2
+ @description = 'Create new files'
3
+ end
4
+
5
+ require 'noir/command/new/note'
@@ -0,0 +1,16 @@
1
+ require 'date'
2
+ require 'fileutils'
3
+
4
+ class Noir::Command::New::Note < Noir::Base::TerminalCommand
5
+ @description = 'create empty txt. filename format is <serial-no>_<date>.txt'
6
+
7
+ class << self
8
+
9
+ def execute *args
10
+ note_num = Dir.glob('[0-9]*_????????.txt').size + 1
11
+ note_name = format("%02d", note_num) + '_' + Time.now.strftime('%Y%m%d') + '.txt'
12
+ FileUtils.touch(note_name)
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ module Noir
2
+ class Executer
3
+
4
+ def self.command_from_argv
5
+ 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
28
+ end
29
+
30
+ return command || Noir::Command # default command
31
+ end
32
+
33
+ def self.args_from_argv
34
+ argv = ARGV.clone
35
+ command_str = self.command_from_argv.to_s.sub(/^Noir::Command/, '')
36
+ command_str = command_str.sub(/^::/, '')
37
+ command_size = command_str.split('::').size
38
+ return argv.drop(command_size)
39
+ end
40
+
41
+ def self.execute
42
+ command_from_argv.execute *args_from_argv
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ require 'optparse'
2
+
3
+ module Noir
4
+
5
+ class Options
6
+
7
+ Help = :help
8
+
9
+ @@options = {}
10
+
11
+ def self.parse_options_from_argv!
12
+ parser = OptionParser.new
13
+
14
+ parser.program_name = 'noir'
15
+ parser.version = Noir::VERSION
16
+ parser.on('-h', '--help'){|v| @@options[Noir::Options::Help] = v}
17
+
18
+ parser.parse!(ARGV)
19
+
20
+ @@options
21
+ end
22
+
23
+ def self.exist? const_symbol = nil
24
+ @@options.has_key?(const_symbol)
25
+ end
26
+ end
27
+
28
+ end
29
+
@@ -0,0 +1,3 @@
1
+ module Noir
2
+ VERSION = "0.0.1"
3
+ end
data/noir.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'noir/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "noir"
8
+ spec.version = Noir::VERSION
9
+ spec.authors = ["atton"]
10
+ spec.email = ["e115763@gmail.com"]
11
+ spec.summary = %q{Utilities for atton.}
12
+ spec.description = %q{Untility commands with completion for atton.}
13
+ spec.homepage = "http://github.com/atton-/noir"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake", "10.1.1"
23
+ spec.add_development_dependency "rspec", "3.0.0.beta2"
24
+ end
@@ -0,0 +1,75 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Command::Completion' do
5
+ it 'is Noir::Command::TerminalCommand' do
6
+ expect(Noir::Command::Completion.class).to eq(Class)
7
+ end
8
+
9
+ describe 'suggestions' do
10
+ before do
11
+ stub_commands
12
+ end
13
+
14
+ it 'return all command from nil' do
15
+ expect(Noir::Command::Completion.suggestions([])).to include('hoge')
16
+ expect(Noir::Command::Completion.suggestions([])).to include('fuga')
17
+ end
18
+
19
+ it 'return nil from unmatched pattern' do
20
+ expect(Noir::Command::Completion.suggestions(['piyo'])).to eq([])
21
+ end
22
+
23
+ it 'return matched command name' do
24
+ list = ['h']
25
+ expect(Noir::Command::Completion.suggestions(list)).to include('hoge')
26
+ expect(Noir::Command::Completion.suggestions(list)).to_not include('fuga')
27
+ end
28
+
29
+ it 'return command list in sub command' do
30
+ list = ['hoge']
31
+ expect(Noir::Command::Completion.suggestions(list)).to include('subcommand')
32
+ expect(Noir::Command::Completion.suggestions(list)).to include('subcommandtwo')
33
+ expect(Noir::Command::Completion.suggestions(list)).to_not include('subsubcommand')
34
+ end
35
+
36
+ it 'return matched command name list in sub command' do
37
+ list = ['hoge', 's']
38
+ expect(Noir::Command::Completion.suggestions(list)).to include('subcommand')
39
+ expect(Noir::Command::Completion.suggestions(list)).to include('subcommandtwo')
40
+ expect(Noir::Command::Completion.suggestions(list)).to_not include('subsubcommand')
41
+ end
42
+
43
+ it 'return empty when not matched name in command' do
44
+ list = ['hoge', 'p']
45
+ expect(Noir::Command::Completion.suggestions(list)).to eq([])
46
+ end
47
+
48
+ it 'return sub sub commands list in sub command' do
49
+ list = ['hoge', 'subcommand']
50
+ expect(Noir::Command::Completion.suggestions(list)).to include('subsubcommand')
51
+ expect(Noir::Command::Completion.suggestions(list)).to_not include('subcommand')
52
+ end
53
+
54
+ it 'return empty when not matched name in sub sub command' do
55
+ list = ['hoge', 'subcommand', 's']
56
+ expect(Noir::Command::Completion.suggestions(list)).to include('subsubcommand')
57
+ expect(Noir::Command::Completion.suggestions(list)).to_not include('subcommand')
58
+ end
59
+
60
+ it 'return empty when not matched name in sub command' do
61
+ list = ['hoge', 'subcommand', 'aaaaaaa']
62
+ expect(Noir::Command::Completion.suggestions(list)).to eq([])
63
+ end
64
+
65
+ it 'return empty in terminal command' do
66
+ list = ['hoge', 'subcommand', 'subsubcommand']
67
+ expect(Noir::Command::Completion.suggestions(list)).to eq([])
68
+ end
69
+
70
+ it 'return empty in terminal command' do
71
+ list = ['fuga']
72
+ expect(Noir::Command::Completion.suggestions(list)).to eq([])
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,16 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Command::Help' do
5
+ it 'is inherited Noir::Base::TerminalCommand' do
6
+ expect(Noir::Command::Help.ancestors).to include(Noir::Base::TerminalCommand)
7
+ end
8
+
9
+ it 'is output when execute' do
10
+ expect{Noir::Command::Help.execute}.to output.to_stdout
11
+ end
12
+
13
+ it 'is raise exception when apply arguments' do
14
+ expect{Noir::Command::Help.execute 'abc'}.to raise_error
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Command::Init::Zsh' do
5
+ it 'is inherited Noir::Base::TerminalCommand' do
6
+ expect(Noir::Command::Init::Zsh.superclass).to eq(Noir::Base::TerminalCommand)
7
+ end
8
+
9
+ it 'is output in execute' do
10
+ expect{expect{Noir::Command::Init::Zsh.execute []}.to output.to_stdout}.to_not raise_error
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Command::Init' do
5
+ it 'is inherited Noir::Base::Command' do
6
+ expect(Noir::Command::Init.superclass).to eq(Noir::Base::Command)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Command::New::Note' do
5
+ it 'is TerminalCommand' do
6
+ expect(Noir::Command::New::Note.superclass).to eq(Noir::Base::TerminalCommand)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Command::New' do
5
+ it 'is Command' do
6
+ expect(Noir::Command::New.superclass).to eq(Noir::Base::Command)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Command' do
5
+ it 'is Class' do
6
+ expect(Noir::Command.class).to eq(Class)
7
+ end
8
+ end
@@ -0,0 +1,167 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Executer' do
5
+
6
+ # define command for tests
7
+ before do
8
+ stub_commands
9
+ end
10
+
11
+ it 'is class' do
12
+ expect(Noir::Executer.class).to eq(Class)
13
+ end
14
+
15
+ describe 'command_from_argv' do
16
+
17
+ describe 'in undefined argv' do
18
+ before do
19
+ stub_const('ARGV', [])
20
+ stub_const('Noir::Command::Help', Class.new(Noir::Base::Command))
21
+ end
22
+
23
+ it 'return Noir::Command' do
24
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command)
25
+ end
26
+ end
27
+
28
+ describe 'in defined argv' do
29
+
30
+ it 'return command' do
31
+ stub_const 'ARGV', ['hoge']
32
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
33
+ end
34
+
35
+ it 'return command if has other arguments' do
36
+ stub_const 'ARGV', ['hoge', 'aaa']
37
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
38
+ end
39
+
40
+ it 'return command if has sub non command' do
41
+ stub_const 'ARGV', ['hoge', 'SubNonCommand']
42
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge)
43
+ end
44
+
45
+ it 'return sub command' do
46
+ stub_const 'ARGV', ['hoge', 'subcommand']
47
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommand)
48
+ end
49
+
50
+ it 'return sub command if has other arguments' do
51
+ stub_const 'ARGV', ['hoge', 'subcommand', 'aaa']
52
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommand)
53
+ end
54
+
55
+ it 'return sub command if has sub non command' do
56
+ stub_const 'ARGV', ['hoge', 'SubCommand', 'SubSubNonCommand']
57
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommand)
58
+ end
59
+
60
+ it 'return sub sub command' do
61
+ stub_const 'ARGV', ['hoge', 'subcommand', 'subsubcommand']
62
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommand::SubSubCommand)
63
+ end
64
+
65
+ it 'return sub sub command if has other arguments' do
66
+ stub_const 'ARGV', ['hoge', 'subcommand', 'subsubcommand', 'aaa']
67
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Hoge::SubCommand::SubSubCommand)
68
+ end
69
+
70
+ it 'return terminal command' do
71
+ stub_const 'ARGV', ['fuga']
72
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Fuga)
73
+ end
74
+
75
+ it 'return terminal command if has other arguments' do
76
+ stub_const 'ARGV', ['fuga', 'aaa']
77
+ expect(Noir::Executer.command_from_argv).to eq(Noir::Command::Fuga)
78
+ end
79
+
80
+ end
81
+ end
82
+
83
+ describe 'args_from_argv' do
84
+
85
+ describe 'in undefined ARGV' do
86
+ before { stub_const('ARGV', []) }
87
+
88
+ it 'return []' do
89
+ expect(Noir::Executer.args_from_argv).to eq([])
90
+ end
91
+ end
92
+
93
+ describe 'in defined argv' do
94
+
95
+ it 'return [] if only command' do
96
+ stub_const 'ARGV', ['hoge']
97
+ expect(Noir::Executer.args_from_argv).to eq([])
98
+ end
99
+
100
+ it 'return single arg if argv is comamnd + arg' do
101
+ stub_const 'ARGV', ['hoge', 'aaa']
102
+ expect(Noir::Executer.args_from_argv).to eq(['aaa'])
103
+ end
104
+
105
+ it 'return multi arg if argv is comamnd + args' do
106
+ stub_const 'ARGV', ['hoge', 'aaa', 'bbb']
107
+ expect(Noir::Executer.args_from_argv).to eq(['aaa', 'bbb'])
108
+ end
109
+
110
+ it 'return single arg if argv is command + sub non command' do
111
+ stub_const 'ARGV', ['hoge', 'SubNonCommand']
112
+ expect(Noir::Executer.args_from_argv).to eq(['SubNonCommand'])
113
+ end
114
+
115
+ it 'return [] if argv is command + sub command' do
116
+ stub_const 'ARGV', ['hoge', 'subcommand']
117
+ expect(Noir::Executer.args_from_argv).to eq([])
118
+ end
119
+
120
+ it 'return single arg if argv is command + sub command + arg' do
121
+ stub_const 'ARGV', ['hoge', 'subcommand', 'aaa']
122
+ expect(Noir::Executer.args_from_argv).to eq(['aaa'])
123
+ end
124
+
125
+ it 'return multi arg if argv is command + sub command + args' do
126
+ stub_const 'ARGV', ['hoge', 'subcommand', 'aaa', 'bbb']
127
+ expect(Noir::Executer.args_from_argv).to eq(['aaa', 'bbb'])
128
+ end
129
+
130
+ it 'return single arg if argv is command + sub command + subsubnoncommand' do
131
+ stub_const 'ARGV', ['hoge', 'SubCommand', 'SubSubNonCommand']
132
+ expect(Noir::Executer.args_from_argv).to eq(['SubSubNonCommand'])
133
+ end
134
+
135
+ it 'return [] if argv is command + sub command + sub sub command' do
136
+ stub_const 'ARGV', ['hoge', 'subcommand', 'subsubcommand']
137
+ expect(Noir::Executer.args_from_argv).to eq([])
138
+ end
139
+
140
+ it 'return single arg, if argv is command + sub command + sub sub command + arg' do
141
+ stub_const 'ARGV', ['hoge', 'subcommand', 'subsubcommand', 'aaa']
142
+ expect(Noir::Executer.args_from_argv).to eq(['aaa'])
143
+ end
144
+
145
+ it 'return multi arg, if argv is command + sub command + sub sub command + args' do
146
+ stub_const 'ARGV', ['hoge', 'subcommand', 'subsubcommand', 'aaa', 'bbb']
147
+ expect(Noir::Executer.args_from_argv).to eq(['aaa', 'bbb'])
148
+ end
149
+
150
+ it 'return [] if argv is terminal command' do
151
+ stub_const 'ARGV', ['fuga']
152
+ expect(Noir::Executer.args_from_argv).to eq([])
153
+ end
154
+
155
+ it 'return single arg, if argv is terminal command + arg' do
156
+ stub_const 'ARGV', ['fuga', 'aaa']
157
+ expect(Noir::Executer.args_from_argv).to eq(['aaa'])
158
+ end
159
+
160
+ it 'return single arg, if argv is terminal command + args' do
161
+ stub_const 'ARGV', ['fuga', 'aaa', 'bbb']
162
+ expect(Noir::Executer.args_from_argv).to eq(['aaa', 'bbb'])
163
+ end
164
+
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,119 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Base::Command' do
5
+
6
+ it 'is class' do
7
+ expect(Noir::Base::Command.class).to eq(Class)
8
+ end
9
+
10
+ describe 'Command.description' do
11
+ it 'raise exception if description is nil.' do
12
+ expect{Noir::Base::Command.description}.to raise_error(RuntimeError)
13
+ end
14
+
15
+ it 'output description if description is not nil' do
16
+ Noir::Base::Command.instance_variable_set :@description, "hoge"
17
+ expect{Noir::Base::Command.description}.to output.to_stdout
18
+ Noir::Base::Command.instance_variable_set :@description, nil
19
+ end
20
+
21
+ it 'not effect that set description into superclass to subclass' do
22
+ Noir::Base::Command.class_variable_set :@@description, "hoge"
23
+ stub_const('Hoge', Class.new(Noir::Base::Command))
24
+ expect{Hoge.description}.to raise_error
25
+ Noir::Base::Command.class_variable_set :@@description, nil
26
+ end
27
+ end
28
+
29
+ describe 'Command.execute' do
30
+ before { stub_const('Hoge', Class.new(Noir::Base::Command)) }
31
+
32
+ it 'raise exception if called in not extended class' do
33
+ expect{Noir::Base::Command.execute}.to raise_error(RuntimeError)
34
+ end
35
+
36
+ it 'raise exception if called in extended class but undefined description' do
37
+ expect{Hoge.execute}.to raise_error
38
+ end
39
+
40
+ it 'output description if called in extended class and defined description' do
41
+ Hoge.instance_variable_set :@description, "hoge"
42
+ expect{Hoge.execute}.to output.to_stdout
43
+ end
44
+ end
45
+
46
+ describe 'Command.sub_commands' do
47
+ it 'return [] when not defined sub commands' do
48
+ expect(Noir::Base::Command.sub_commands).to eq([])
49
+ end
50
+
51
+ describe 'when defined sub commands.' do
52
+ before do
53
+ stub_const('Hoge' , Class.new(Noir::Base::Command))
54
+ stub_const('Hoge::SubCommand' , Class.new(Noir::Base::Command))
55
+ stub_const('Hoge::SubCommand::SubSubCommand' , Class.new(Noir::Base::Command))
56
+ stub_const('Hoge::SubCommand::SubSubNonCommand' , Class.new)
57
+ stub_const('Hoge::SubCommandTwo' , Class.new(Noir::Base::Command))
58
+ stub_const('Hoge::SubNonCommand' , Class.new)
59
+
60
+ =begin
61
+ # stub_const is this structure
62
+ class Hoge < Noir::Base::Command
63
+ class SubCommand < Noir::Base::Command
64
+ class SubSubCommand < Noir::Base::Command
65
+ end
66
+ class SubSubNonCommand
67
+ end
68
+ end
69
+ class SubCommandTwo < Noir::Base::Command
70
+ end
71
+
72
+ class SubNonCommand
73
+ end
74
+ end
75
+ =end
76
+
77
+ @commands = Hoge.sub_commands
78
+ end
79
+
80
+ it 'return subcommands' do
81
+ expect(@commands).to eq([:SubCommand, :SubCommandTwo])
82
+ end
83
+
84
+ it 'not include symbol that not inherited Noir::Base::Command' do
85
+ expect(@commands).not_to include(:SubNonCommand)
86
+ end
87
+
88
+ it 'not include symbol that subsub command' do
89
+ expect(@commands).not_to include(:SubSubCommand)
90
+ end
91
+
92
+ it 'not include self' do
93
+ expect(@commands).not_to include(:Hoge)
94
+ end
95
+
96
+ describe 'in sub command' do
97
+ before { @commands = Hoge::SubCommand.sub_commands }
98
+
99
+ it 'return sub sub command' do
100
+ expect(@commands).to eq([:SubSubCommand])
101
+ end
102
+
103
+ it 'not include sub sub non command' do
104
+ expect(@commands).not_to include(:SubSubNonCommand)
105
+ end
106
+
107
+ it 'not include sub command' do
108
+ expect(@commands).not_to include(:SubCommand, :SubCommandTwo, :SubNonCommand)
109
+ end
110
+
111
+ it 'not include self class' do
112
+ expect(@commands).not_to include(:SubCommand)
113
+ end
114
+
115
+ end
116
+ end
117
+
118
+ end
119
+ end
@@ -0,0 +1,33 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Base::TerminalCommand' do
5
+
6
+ it 'is class' do
7
+ expect(Noir::Base::TerminalCommand.class).to eq(Class)
8
+ end
9
+
10
+ it 'is inherited Noir::Base::Command' do
11
+ expect(Noir::Base::TerminalCommand.ancestors).to include(Noir::Base::Command)
12
+ end
13
+
14
+ describe '.execute' do
15
+ before { stub_const('Hoge', Class.new(Noir::Base::TerminalCommand)) }
16
+
17
+ it 'raise exception when not overrided' do
18
+ expect{Noir::Base::TerminalCommand.execute}.to raise_error(RuntimeError, /^called raw/)
19
+ end
20
+
21
+ it 'raise exception in extended class not overrided' do
22
+ expect{Hoge.execute}.to raise_error(RuntimeError, /^please override/)
23
+ end
24
+
25
+ it 'raise exception in extended class not overrided' do
26
+ def Hoge.execute *args
27
+ puts "hoge"
28
+ end
29
+ expect{Hoge.execute}.to output("hoge\n").to_stdout
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,10 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Base' do
5
+
6
+ it "is module" do
7
+ expect(Noir::Base.class).to eq(Module)
8
+ end
9
+
10
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'noir'
3
+
4
+ describe Noir do
5
+
6
+
7
+ it 'is can access Noir::VERSION' do
8
+ expect(Noir.class_eval('Noir::VERSION.class')).to eq(String)
9
+ end
10
+
11
+ it 'is can access Noir::Options' do
12
+ expect(Noir.class_eval('Noir::Options.class')).to eq(Class)
13
+ end
14
+
15
+ it 'is can access Noir::Base' do
16
+ expect(Noir.class_eval('Noir::Base.class')).to eq(Module)
17
+ end
18
+
19
+ it 'is can access Noir::Base::Command' do
20
+ expect(Noir.class_eval('Noir::Base::Command.class')).to eq(Class)
21
+ end
22
+
23
+ it 'is can access Noir::Base::TerminalCommand' do
24
+ expect(Noir.class_eval('Noir::Base::TerminalCommand.class')).to eq(Class)
25
+ end
26
+
27
+ end
@@ -0,0 +1,52 @@
1
+ require 'noir'
2
+ require 'spec_helper'
3
+
4
+ describe 'Noir::Options' do
5
+
6
+ it 'is Class' do
7
+ expect(Noir::Options.class).to eq(Class)
8
+ end
9
+
10
+ describe 'Noir::Options.exist?' do
11
+ after {Noir::Options.class_variable_set :@@options, {}}
12
+
13
+ it 'is return false if argument is nil.' do
14
+ expect(Noir::Options.exist? nil).to eq(false)
15
+ end
16
+
17
+ it '(Help) is return false if ARGV not include "-h"' do
18
+ expect(Noir::Options.exist? Noir::Options::Help).to eq(false)
19
+ end
20
+
21
+ it '(Help) is return true if ARGV include "-h"' do
22
+ stub_const('ARGV', ['-h'])
23
+ Noir::Options.parse_options_from_argv!
24
+ expect(Noir::Options.exist? Noir::Options::Help).to eq(true)
25
+ end
26
+
27
+ it '(Help) is return false if ARGV not include "--help"' do
28
+ expect(Noir::Options.exist? Noir::Options::Help).to eq(false)
29
+ end
30
+
31
+ it '(Help) is return true if ARGV include "--help"' do
32
+ stub_const('ARGV', ['--help'])
33
+ Noir::Options.parse_options_from_argv!
34
+ expect(Noir::Options.exist? Noir::Options::Help).to eq(true)
35
+ end
36
+
37
+ it 'exit with output version if ARGV include "-v"' do
38
+ stub_const('ARGV', ['-v'])
39
+ expect {
40
+ expect{Noir::Options.parse_options_from_argv!}.to raise_error(SystemExit)
41
+ }.to output('noir ' + Noir::VERSION + "\n").to_stdout
42
+ end
43
+
44
+ it 'exit with output version if ARGV include "--version"' do
45
+ stub_const('ARGV', ['--version'])
46
+ expect {
47
+ expect{Noir::Options.parse_options_from_argv!}.to raise_error(SystemExit)
48
+ }.to output('noir ' + Noir::VERSION + "\n").to_stdout
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,37 @@
1
+ require 'noir'
2
+
3
+ $LOAD_PATH << File.expand_path('../../lib', __FILE__)
4
+
5
+ # utils
6
+
7
+ def stub_commands
8
+ stub_const('Noir::Command::Hoge' , Class.new(Noir::Base::Command))
9
+ stub_const('Noir::Command::Hoge::SubCommand' , Class.new(Noir::Base::Command))
10
+ stub_const('Noir::Command::Hoge::SubCommand::SubSubCommand' , Class.new(Noir::Base::Command))
11
+ stub_const('Noir::Command::Hoge::SubCommand::SubSubNonCommand' , Class.new)
12
+ stub_const('Noir::Command::Hoge::SubCommandTwo' , Class.new(Noir::Base::Command))
13
+ stub_const('Noir::Command::Hoge::SubNonCommand' , Class.new)
14
+ stub_const('Noir::Command::Fuga' , Class.new(Noir::Base::TerminalCommand))
15
+
16
+ =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
31
+ end
32
+ class Fuga < Noir::Base::TerminalCommand
33
+ end
34
+ end
35
+ =end
36
+
37
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: noir
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - atton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 10.1.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 10.1.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.0.0.beta2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0.beta2
55
+ description: Untility commands with completion for atton.
56
+ email:
57
+ - e115763@gmail.com
58
+ executables:
59
+ - noir
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - bin/noir
69
+ - lib/noir.rb
70
+ - lib/noir/base.rb
71
+ - lib/noir/base/command.rb
72
+ - lib/noir/base/terminal_command.rb
73
+ - lib/noir/command.rb
74
+ - lib/noir/command/completion.rb
75
+ - lib/noir/command/help.rb
76
+ - lib/noir/command/init.rb
77
+ - lib/noir/command/init/zsh.rb
78
+ - lib/noir/command/new.rb
79
+ - lib/noir/command/new/note.rb
80
+ - lib/noir/executer.rb
81
+ - lib/noir/options.rb
82
+ - lib/noir/version.rb
83
+ - noir.gemspec
84
+ - spec/noir/command/completion_spec.rb
85
+ - spec/noir/command/help_spec.rb
86
+ - spec/noir/command/init/zsh_spec.rb
87
+ - spec/noir/command/init_spec.rb
88
+ - spec/noir/command/new/note_spec.rb
89
+ - spec/noir/command/new_spec.rb
90
+ - spec/noir/command_spec.rb
91
+ - spec/noir/executer_spec.rb
92
+ - spec/noir/noir/base/command_spec.rb
93
+ - spec/noir/noir/base/terminal_command_spec.rb
94
+ - spec/noir/noir/base_spec.rb
95
+ - spec/noir/noir_spec.rb
96
+ - spec/noir/options_spec.rb
97
+ - spec/spec_helper.rb
98
+ homepage: http://github.com/atton-/noir
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.2.2
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Utilities for atton.
122
+ test_files:
123
+ - spec/noir/command/completion_spec.rb
124
+ - spec/noir/command/help_spec.rb
125
+ - spec/noir/command/init/zsh_spec.rb
126
+ - spec/noir/command/init_spec.rb
127
+ - spec/noir/command/new/note_spec.rb
128
+ - spec/noir/command/new_spec.rb
129
+ - spec/noir/command_spec.rb
130
+ - spec/noir/executer_spec.rb
131
+ - spec/noir/noir/base/command_spec.rb
132
+ - spec/noir/noir/base/terminal_command_spec.rb
133
+ - spec/noir/noir/base_spec.rb
134
+ - spec/noir/noir_spec.rb
135
+ - spec/noir/options_spec.rb
136
+ - spec/spec_helper.rb