shellissimo 0.0.1 → 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 +7 -0
- data/.travis.yml +8 -0
- data/README.md +52 -5
- data/lib/shellissimo.rb +0 -1
- data/lib/shellissimo/command.rb +16 -3
- data/lib/shellissimo/command_name.rb +7 -8
- data/lib/shellissimo/command_param.rb +23 -0
- data/lib/shellissimo/command_param_validator.rb +42 -0
- data/lib/shellissimo/commands_collection.rb +36 -0
- data/lib/shellissimo/dsl.rb +10 -10
- data/lib/shellissimo/dsl/command_builder.rb +39 -2
- data/lib/shellissimo/dsl/command_param_builder.rb +55 -0
- data/lib/shellissimo/help.rb +52 -0
- data/lib/shellissimo/input_parser.rb +2 -2
- data/lib/shellissimo/shell.rb +3 -9
- data/lib/shellissimo/version.rb +1 -1
- data/shellissimo.gemspec +5 -2
- data/test/lib/shellissimo/dsl/test_command_builder.rb +69 -0
- data/test/lib/shellissimo/dsl/test_command_param_builder.rb +41 -0
- data/test/lib/shellissimo/test_command.rb +24 -0
- data/test/lib/shellissimo/test_command_name.rb +15 -7
- data/test/lib/shellissimo/test_command_param.rb +31 -0
- data/test/lib/shellissimo/test_command_param_validator.rb +49 -0
- data/test/lib/shellissimo/test_commands_collection.rb +33 -0
- data/test/lib/shellissimo/test_dsl.rb +13 -22
- data/test/lib/shellissimo/test_input_parser.rb +2 -3
- data/test/test_helper.rb +12 -6
- metadata +60 -30
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b74cb3f6faba944fab76670f0d5c9769c8b44387
|
4
|
+
data.tar.gz: 920d6f8e50bb5bd2b5cc1a65fc7bf45ddf195401
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3a40da683fcc53aa0fb493bad3ba0354cbb377bba037c127e5a9acf5fb7b897120921b5fd963bea814a69f514b6435075509361d3ae9acb6984fc8976c51440d
|
7
|
+
data.tar.gz: 2471579d9177cd250f21b9882c85ba0eb0fc24a1235b955d1654cab0937de6e14ae6ae472654f8f8e22f2d663b04b07f0fa871751acc1641e2e4b7ae196df903
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
-
|
1
|
+
Shellissimo
|
2
|
+
===========
|
3
|
+
|
4
|
+
[](http://travis-ci.org/v-yarotsky/shellissimo)
|
5
|
+
[](https://coveralls.io/r/v-yarotsky/shellissimo)
|
6
|
+
[](https://codeclimate.com/github/v-yarotsky/shellissimo)
|
7
|
+
[](http://badge.fury.io/rb/shellissimo)
|
2
8
|
|
3
9
|
Minimalistic framework for constructing shell-like applications.
|
4
10
|
|
5
|
-
|
11
|
+
Installation
|
12
|
+
---------------
|
6
13
|
|
7
14
|
Add this line to your application's Gemfile:
|
8
15
|
|
@@ -16,11 +23,51 @@ Or install it yourself as:
|
|
16
23
|
|
17
24
|
$ gem install shellissimo
|
18
25
|
|
19
|
-
|
26
|
+
Usage
|
27
|
+
-----
|
28
|
+
|
29
|
+
Create your shell by sublcassing ``Shellissimo::Shell``
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'shellissimo'
|
33
|
+
|
34
|
+
class Greeter; def say_hi(name, title); p "hi #{title} #{name}"; end; end
|
35
|
+
|
36
|
+
class MyShell < Shellissimo::Shell
|
37
|
+
command :hi do |c|
|
38
|
+
c.description "Says hello to the user"
|
39
|
+
c.mandatory_param(:user) do |p|
|
40
|
+
p.description "User name"
|
41
|
+
p.validate { |v| !v.to_s.strip.empty? }
|
42
|
+
end
|
43
|
+
c.param(:title) do |p|
|
44
|
+
p.validate { |v| %w(Mr. Ms.).include?(v.to_s) }
|
45
|
+
end
|
46
|
+
c.run { |params| @greeter.say_hi(params[:user], params[:title]) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize
|
50
|
+
@greeter = Greeter.new
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
MyShell.new.run
|
56
|
+
```
|
57
|
+
|
58
|
+
In this example help message would look like:
|
59
|
+
|
60
|
+
Available commands:
|
61
|
+
|
62
|
+
hi - Says hello to the user
|
63
|
+
user - User name - mandatory
|
64
|
+
title - optional
|
20
65
|
|
21
|
-
|
66
|
+
help (aliases: h) - Show available commands
|
67
|
+
quit (aliases: exit) - Quit irb
|
22
68
|
|
23
|
-
|
69
|
+
Contributing
|
70
|
+
------------
|
24
71
|
|
25
72
|
1. Fork it
|
26
73
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
data/lib/shellissimo.rb
CHANGED
data/lib/shellissimo/command.rb
CHANGED
@@ -3,10 +3,11 @@ require 'shellissimo/command_name'
|
|
3
3
|
module Shellissimo
|
4
4
|
|
5
5
|
class Command
|
6
|
-
attr_reader :name, :aliases, :description, :
|
6
|
+
attr_reader :name, :aliases, :description, :param_definitions, :block
|
7
7
|
|
8
|
-
def initialize(name, description = "", aliases = [],
|
9
|
-
@name, @description
|
8
|
+
def initialize(name, description = "", aliases = [], param_definitions = [], &block)
|
9
|
+
@name, @description = CommandName.new(name, aliases), String(description)
|
10
|
+
@param_definitions = Array(param_definitions)
|
10
11
|
self.block = block
|
11
12
|
end
|
12
13
|
|
@@ -15,6 +16,7 @@ module Shellissimo
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def prepend_params(params)
|
19
|
+
params = filter_params(params)
|
18
20
|
old_block = block # let's fool ruby
|
19
21
|
dup.tap { |c| c.block = proc { instance_exec(params, &old_block) } }
|
20
22
|
end
|
@@ -27,6 +29,17 @@ module Shellissimo
|
|
27
29
|
def to_proc
|
28
30
|
block
|
29
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def filter_params(params)
|
36
|
+
filtered = {}
|
37
|
+
@param_definitions.each do |p|
|
38
|
+
raise ArgumentError, "param '#{p.name}' is not valid!" unless p.valid?(params[p.name])
|
39
|
+
filtered[p.name] = params[p.name]
|
40
|
+
end
|
41
|
+
filtered.merge(params)
|
42
|
+
end
|
30
43
|
end
|
31
44
|
|
32
45
|
end
|
@@ -6,8 +6,8 @@ module Shellissimo
|
|
6
6
|
attr_reader :name, :aliases
|
7
7
|
|
8
8
|
def initialize(name, aliases = [])
|
9
|
-
|
10
|
-
|
9
|
+
raise ArgumentError, "command name can't be blank" if String(name).empty?
|
10
|
+
@name, @aliases = name.to_sym, Array(aliases).map(&:to_sym)
|
11
11
|
end
|
12
12
|
|
13
13
|
def hash
|
@@ -19,13 +19,16 @@ module Shellissimo
|
|
19
19
|
when CommandName
|
20
20
|
return true if other.equal? self
|
21
21
|
return true if name == other.name && aliases == other.aliases
|
22
|
+
false
|
22
23
|
when String, Symbol
|
23
|
-
return true if other.
|
24
|
-
return true if @aliases.include?(other.
|
24
|
+
return true if other.to_sym == @name
|
25
|
+
return true if @aliases.include?(other.to_sym)
|
26
|
+
false
|
25
27
|
else
|
26
28
|
false
|
27
29
|
end
|
28
30
|
end
|
31
|
+
alias :eql? :==
|
29
32
|
|
30
33
|
def <=>(other)
|
31
34
|
self == other or name <=> other.name
|
@@ -36,10 +39,6 @@ module Shellissimo
|
|
36
39
|
result += " (aliases: #{aliases.join(", ")})" unless aliases.empty?
|
37
40
|
result
|
38
41
|
end
|
39
|
-
|
40
|
-
def inspect
|
41
|
-
"<CommandName:#{self.object_id} name: #{@name.inspect}, aliases: #{@aliases.inspect}"
|
42
|
-
end
|
43
42
|
end
|
44
43
|
|
45
44
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'shellissimo/command_param_validator'
|
2
|
+
|
3
|
+
module Shellissimo
|
4
|
+
|
5
|
+
class CommandParam
|
6
|
+
attr_reader :description, :validator
|
7
|
+
|
8
|
+
def initialize(name, validator = nil, description = "")
|
9
|
+
@name, @description = String(name), String(description)
|
10
|
+
raise ArgumentError, "command param name can't be blank" if @name.empty?
|
11
|
+
@validator = validator || CommandParamValidator.noop
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
@name.to_sym
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid?(value)
|
19
|
+
!!@validator[value]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Shellissimo
|
2
|
+
|
3
|
+
class CommandParamValidator
|
4
|
+
attr_reader :description, :block
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def noop
|
8
|
+
new { |v| true }
|
9
|
+
end
|
10
|
+
|
11
|
+
def optional
|
12
|
+
new("optional") { |v| v.nil? }
|
13
|
+
end
|
14
|
+
|
15
|
+
def mandatory
|
16
|
+
new("mandatory") { |v| !v.nil? }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(description = "", &block)
|
21
|
+
@description = description
|
22
|
+
@block = block or
|
23
|
+
raise ArgumentError, "command param validator block can't be blank"
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(value)
|
27
|
+
@block.call(value)
|
28
|
+
end
|
29
|
+
alias :[] :call
|
30
|
+
|
31
|
+
def &(other)
|
32
|
+
CommandParamValidator.new(description) { |value| block[value] && other.block[value] }
|
33
|
+
end
|
34
|
+
|
35
|
+
def |(other)
|
36
|
+
CommandParamValidator.new(description) { |value| block[value] || other.block[value] }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Shellissimo
|
4
|
+
|
5
|
+
class CommandsCollection
|
6
|
+
include Enumerable
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :@commands, :size
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@commands = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_by_name_or_alias(name_or_alias)
|
16
|
+
@commands.detect { |c| c.name == name_or_alias } or
|
17
|
+
raise CommandNotFoundError, "Command #{name_or_alias} not found"
|
18
|
+
end
|
19
|
+
alias :[] :find_by_name_or_alias
|
20
|
+
|
21
|
+
def each(&block)
|
22
|
+
@commands.each(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def <<(command)
|
26
|
+
@commands << command
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def push(*commands)
|
31
|
+
@commands.push(*commands)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/lib/shellissimo/dsl.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'shellissimo/dsl/command_builder'
|
2
|
+
require 'shellissimo/commands_collection'
|
2
3
|
|
3
4
|
module Shellissimo
|
4
5
|
class CommandNotFoundError < StandardError; end
|
@@ -20,23 +21,22 @@ module Shellissimo
|
|
20
21
|
def command(name)
|
21
22
|
builder = CommandBuilder.new(name)
|
22
23
|
yield builder
|
23
|
-
|
24
|
+
add_command(builder.result)
|
24
25
|
end
|
25
|
-
|
26
26
|
end
|
27
27
|
|
28
28
|
module ClassMethods
|
29
29
|
#
|
30
|
-
# @return [
|
30
|
+
# @return [CommandsCollection] a list of defined commands
|
31
31
|
#
|
32
32
|
def commands
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
CommandsCollection.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_command(command)
|
37
|
+
new_commands = (commands << command)
|
38
|
+
define_singleton_method :commands do
|
39
|
+
new_commands
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'shellissimo/command'
|
2
|
+
require 'shellissimo/dsl/command_param_builder'
|
2
3
|
|
3
4
|
module Shellissimo
|
4
5
|
module DSL
|
5
6
|
|
6
7
|
class CommandBuilder
|
7
|
-
def initialize(name)
|
8
|
+
def initialize(name, param_builder_class = CommandParamBuilder)
|
8
9
|
@name = name
|
10
|
+
@param_definitions = []
|
11
|
+
@param_builder_class = param_builder_class
|
9
12
|
end
|
10
13
|
|
11
14
|
def description(desc)
|
@@ -24,8 +27,42 @@ module Shellissimo
|
|
24
27
|
@block = block
|
25
28
|
end
|
26
29
|
|
30
|
+
#
|
31
|
+
# Defines a single command param (optional)
|
32
|
+
# @see CommandParamBuilder
|
33
|
+
# @param name [String] name for command param
|
34
|
+
# @yieldparam [CommandParamBuilder]
|
35
|
+
# @return [CommandParam]
|
36
|
+
#
|
37
|
+
def param(name)
|
38
|
+
build_param(name) do |p|
|
39
|
+
p.optional!
|
40
|
+
yield p if block_given?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Defines mandatory command param
|
46
|
+
# @see #param
|
47
|
+
#
|
48
|
+
def mandatory_param(name)
|
49
|
+
build_param(name) do |p|
|
50
|
+
p.mandatory!
|
51
|
+
yield p if block_given?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
27
55
|
def result
|
28
|
-
Command.new(String(@name), @description, @aliases, &@block)
|
56
|
+
Command.new(String(@name), @description, @aliases, @param_definitions, &@block)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def build_param(name)
|
62
|
+
builder = @param_builder_class.new(name)
|
63
|
+
yield builder if block_given?
|
64
|
+
@param_definitions << builder.result
|
65
|
+
builder.result
|
29
66
|
end
|
30
67
|
end
|
31
68
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'shellissimo/command_param'
|
2
|
+
require 'shellissimo/command_param_validator'
|
3
|
+
|
4
|
+
module Shellissimo
|
5
|
+
module DSL
|
6
|
+
|
7
|
+
class CommandParamBuilder
|
8
|
+
attr_reader :name, :description
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
@validator = CommandParamValidator.noop
|
13
|
+
@kind = :optional
|
14
|
+
end
|
15
|
+
|
16
|
+
def description(desc)
|
17
|
+
@description = desc
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate(description = "", &block)
|
21
|
+
@validator = @validator & CommandParamValidator.new(description, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# @private
|
26
|
+
#
|
27
|
+
def mandatory!
|
28
|
+
@kind = :mandatory
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# @private
|
33
|
+
#
|
34
|
+
def optional!
|
35
|
+
@kind = :optional
|
36
|
+
end
|
37
|
+
|
38
|
+
def result
|
39
|
+
CommandParam.new(@name, validator, @description)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def validator
|
45
|
+
case @kind
|
46
|
+
when :optional
|
47
|
+
CommandParamValidator.optional | @validator
|
48
|
+
when :mandatory
|
49
|
+
CommandParamValidator.mandatory & @validator
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Shellissimo
|
2
|
+
|
3
|
+
#
|
4
|
+
# Generates help secion based on commands defined for a shell
|
5
|
+
#
|
6
|
+
class Help
|
7
|
+
def initialize(commands)
|
8
|
+
@commands = commands
|
9
|
+
@rendered = ""
|
10
|
+
render
|
11
|
+
end
|
12
|
+
|
13
|
+
def rendered
|
14
|
+
@rendered.dup.chomp
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def render
|
20
|
+
line "Available commands:"
|
21
|
+
line
|
22
|
+
@commands.partition { |c| !builtin_commands.include? c }.each do |cs|
|
23
|
+
cs.sort_by(&:name).each(&method(:render_command))
|
24
|
+
line
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def line(str = "")
|
29
|
+
@rendered += "#{str}\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
def builtin_commands
|
33
|
+
%w(help quit).map { |n| @commands[n] }
|
34
|
+
end
|
35
|
+
|
36
|
+
def render_command(cmd)
|
37
|
+
render_name_and_description(cmd.name, "%-40s", cmd.description)
|
38
|
+
cmd.param_definitions.each { |p| render_param(p) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def render_param(param)
|
42
|
+
render_name_and_description(param.name, " %-30s", param.description, param.validator.description)
|
43
|
+
end
|
44
|
+
|
45
|
+
def render_name_and_description(name, name_format, *details)
|
46
|
+
formatted_name = name_format % [name]
|
47
|
+
details.map! { |d| " - %s" % [d] unless d.empty? }
|
48
|
+
line String(formatted_name) + details.join
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -6,7 +6,7 @@ module Shellissimo
|
|
6
6
|
COMMAND_PATTERN = /(\w+)(?:\s*(.*))/
|
7
7
|
|
8
8
|
#
|
9
|
-
# @param commands [
|
9
|
+
# @param commands [CommandsCollection] a list of commands
|
10
10
|
#
|
11
11
|
def initialize(commands)
|
12
12
|
@commands = commands
|
@@ -18,7 +18,7 @@ module Shellissimo
|
|
18
18
|
#
|
19
19
|
def parse_command(line)
|
20
20
|
command_name, command_params = line.match(COMMAND_PATTERN)[1..2]
|
21
|
-
command = @commands
|
21
|
+
command = @commands[command_name]
|
22
22
|
command.prepend_params(parse_params(command_params))
|
23
23
|
end
|
24
24
|
|
data/lib/shellissimo/shell.rb
CHANGED
@@ -2,6 +2,7 @@ require 'readline'
|
|
2
2
|
require 'shellissimo/error_handling'
|
3
3
|
require 'shellissimo/dsl'
|
4
4
|
require 'shellissimo/input_parser'
|
5
|
+
require 'shellissimo/help'
|
5
6
|
|
6
7
|
module Shellissimo
|
7
8
|
|
@@ -39,18 +40,11 @@ module Shellissimo
|
|
39
40
|
command :help do |c|
|
40
41
|
c.shortcut :h
|
41
42
|
c.description "Show available commands"
|
42
|
-
c.run
|
43
|
-
result = "Available commands:\n\n"
|
44
|
-
print_command = proc { |cmd| result += "%-40s - %s\n" % [cmd.name, cmd.description] }
|
45
|
-
commands.partition { |c| !%w(help quit).include? c.name.name }.each do |some_commands|
|
46
|
-
some_commands.sort_by(&:name).each(&print_command)
|
47
|
-
result += "\n"
|
48
|
-
end
|
49
|
-
result.chomp
|
50
|
-
end
|
43
|
+
c.run { |*| Help.new(self.class.commands).rendered }
|
51
44
|
end
|
52
45
|
|
53
46
|
command :quit do |c|
|
47
|
+
c.shortcut :exit
|
54
48
|
c.description "Quit #$0"
|
55
49
|
c.run { |*| exit 0 }
|
56
50
|
end
|
data/lib/shellissimo/version.rb
CHANGED
data/shellissimo.gemspec
CHANGED
@@ -18,7 +18,10 @@ Gem::Specification.new do |gem|
|
|
18
18
|
|
19
19
|
gem.has_rdoc = "yard"
|
20
20
|
|
21
|
-
gem.add_dependency("
|
22
|
-
|
21
|
+
gem.add_dependency("json")
|
22
|
+
|
23
|
+
gem.add_development_dependency("yard")
|
24
|
+
gem.add_development_dependency("redcarpet")
|
23
25
|
gem.add_development_dependency("minitest")
|
26
|
+
gem.add_development_dependency("minitest-reporters")
|
24
27
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'shellissimo/dsl/command_builder'
|
3
|
+
|
4
|
+
include Shellissimo::DSL
|
5
|
+
|
6
|
+
class TestCommandBuilder < ShellissimoTestCase
|
7
|
+
class FakeParamBuilder
|
8
|
+
attr_reader :mandatory, :optional
|
9
|
+
def initialize(*); @mandatory = false; end
|
10
|
+
def mandatory!; @mandatory = true; end
|
11
|
+
def optional!; @optional = true; end
|
12
|
+
def result; end
|
13
|
+
end
|
14
|
+
|
15
|
+
test "sets command name" do
|
16
|
+
assert_equal builder("foo").result.name, "foo"
|
17
|
+
end
|
18
|
+
|
19
|
+
test "#description sets command description" do
|
20
|
+
assert_equal "bar", builder("foo") { |c| c.description "bar" }.result.description
|
21
|
+
end
|
22
|
+
|
23
|
+
test "#shortcut sets command aliases" do
|
24
|
+
assert_equal builder("foo") { |c| c.shortcut :f }.result.name, "f"
|
25
|
+
end
|
26
|
+
|
27
|
+
test "#run sets command block" do
|
28
|
+
assert_equal :hi, builder("foo") { |c| c.run { :hi } }.result.call
|
29
|
+
end
|
30
|
+
|
31
|
+
test "#param creates a param" do
|
32
|
+
assert_includes builder("foo") { |c| c.param("bar") }.result.param_definitions.map(&:name), :bar
|
33
|
+
end
|
34
|
+
|
35
|
+
test "#param yields CommandParamBuilder" do
|
36
|
+
param_builder = nil
|
37
|
+
builder("foo") { |c| c.param("bar") { |p| param_builder = p } }
|
38
|
+
assert_instance_of CommandParamBuilder, param_builder
|
39
|
+
end
|
40
|
+
|
41
|
+
test "#param returns CommandParam" do
|
42
|
+
param = nil
|
43
|
+
builder("foo") { |c| param = c.param("bar") }
|
44
|
+
assert_instance_of Shellissimo::CommandParam, param
|
45
|
+
end
|
46
|
+
|
47
|
+
test "#param yields builder for optional param" do
|
48
|
+
param_builder = nil
|
49
|
+
builder("foo", FakeParamBuilder) { |c| c.param("bar") { |p| param_builder = p } }
|
50
|
+
assert param_builder.optional, "expected param to be built as optional"
|
51
|
+
end
|
52
|
+
|
53
|
+
test "#mandatory_param yields builder with presence validator" do
|
54
|
+
param_builder = nil
|
55
|
+
builder("foo", FakeParamBuilder) { |c| c.mandatory_param("bar") { |p| param_builder = p } }
|
56
|
+
assert param_builder.mandatory, "expected param to be built as mandatory"
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def builder(name, *args)
|
62
|
+
c = CommandBuilder.new(name, *args)
|
63
|
+
c.run {}
|
64
|
+
yield c if block_given?
|
65
|
+
c
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'shellissimo/dsl/command_param_builder'
|
3
|
+
|
4
|
+
include Shellissimo::DSL
|
5
|
+
|
6
|
+
class TestCommandParamBuilder < ShellissimoTestCase
|
7
|
+
test "sets command param name" do
|
8
|
+
assert_equal builder("foo").result.name, :foo
|
9
|
+
end
|
10
|
+
|
11
|
+
test "#description sets command param description" do
|
12
|
+
assert_equal "bar", builder("foo") { |c| c.description "bar" }.result.description
|
13
|
+
end
|
14
|
+
|
15
|
+
test "#mandatory! sets stock validator to mandatory" do
|
16
|
+
refute builder("foo") { |c| c.mandatory! }.result.valid?(nil), "expected param to be mandatory"
|
17
|
+
end
|
18
|
+
|
19
|
+
test "#validate sets validator" do
|
20
|
+
called = false
|
21
|
+
param = builder("foo") { |c| c.validate { |v| called = true } }.result
|
22
|
+
param.valid?(:anything)
|
23
|
+
assert called, "expected validation block to be set"
|
24
|
+
end
|
25
|
+
|
26
|
+
test "#validate respects mandatory/optional" do
|
27
|
+
param = builder("foo") { |c| c.optional!; c.validate { |v| v == 1 } }.result
|
28
|
+
assert param.valid?(nil), "expected param to be optional"
|
29
|
+
refute param.valid?(2), "expected param to be checked by custom validator"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def builder(name)
|
35
|
+
c = CommandParamBuilder.new(name)
|
36
|
+
yield c if block_given?
|
37
|
+
c
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'shellissimo/command'
|
3
|
+
require 'ostruct'
|
3
4
|
|
4
5
|
include Shellissimo
|
5
6
|
|
@@ -21,10 +22,33 @@ class TestCommand < ShellissimoTestCase
|
|
21
22
|
assert called, "expected command block to be called"
|
22
23
|
end
|
23
24
|
|
25
|
+
test "#prepend_params return command copy with curried block" do
|
26
|
+
received_params = {}
|
27
|
+
c = command("foo") { |params| received_params = params }
|
28
|
+
c = c.prepend_params(:foo => 1, :bar => 2)
|
29
|
+
c.call
|
30
|
+
assert_equal ({ :foo => 1, :bar => 2 }), received_params
|
31
|
+
end
|
32
|
+
|
33
|
+
test "#prepend_params runs validations over params" do
|
34
|
+
param_definition = sample_param_definition
|
35
|
+
def param_definition.valid?(*); false; end
|
36
|
+
c = command("foo", "", [], [param_definition]) { |params| received_params = params }
|
37
|
+
assert_raises ArgumentError do
|
38
|
+
c.prepend_params(:removed => 1, :bar => 2)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
24
42
|
private
|
25
43
|
|
26
44
|
def command(*args, &block)
|
27
45
|
Command.new(*args, &block)
|
28
46
|
end
|
47
|
+
|
48
|
+
def sample_param_definition
|
49
|
+
param_definition = OpenStruct.new(:name => :bar)
|
50
|
+
def param_definition.valid?(*); true; end
|
51
|
+
param_definition
|
52
|
+
end
|
29
53
|
end
|
30
54
|
|
@@ -10,37 +10,45 @@ class TestCommandName < ShellissimoTestCase
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
test "
|
13
|
+
test "is equal to itself" do
|
14
14
|
n = command_name("foo")
|
15
15
|
assert_equal n, n
|
16
16
|
end
|
17
17
|
|
18
|
-
test "
|
18
|
+
test "instances are equal if name and aliases are equal" do
|
19
19
|
assert_equal command_name("foo"), command_name("foo")
|
20
20
|
assert_equal command_name("foo", ["baz"]), command_name("foo", ["baz"])
|
21
21
|
end
|
22
22
|
|
23
|
-
test "
|
23
|
+
test "instances are not equal if names aren't equal" do
|
24
24
|
refute_equal command_name("foo"), command_name("bar")
|
25
25
|
end
|
26
26
|
|
27
|
-
test "
|
27
|
+
test "instances are not equal if aliases aren't equal" do
|
28
28
|
refute_equal command_name("foo", ["baz"]), command_name("foo", ["qux"])
|
29
29
|
end
|
30
30
|
|
31
|
-
test "
|
31
|
+
test "is equal to a string if the string is a command's name" do
|
32
32
|
assert_equal command_name("foo"), "foo"
|
33
33
|
end
|
34
34
|
|
35
|
-
test "
|
35
|
+
test "is equal to a string if it is one of command's aliases" do
|
36
36
|
assert_equal command_name("foo", ["bar", "baz"]), "bar"
|
37
37
|
assert_equal command_name("foo", ["bar", "baz"]), "baz"
|
38
38
|
end
|
39
39
|
|
40
|
-
test "
|
40
|
+
test "is not equal to a string that is neither name nor an alias" do
|
41
41
|
refute_equal command_name("foo", ["bar", "baz"]), "qux"
|
42
42
|
end
|
43
43
|
|
44
|
+
test "is not equal to crap" do
|
45
|
+
refute_equal command_name("foo"), 1
|
46
|
+
end
|
47
|
+
|
48
|
+
test "hashes of equal instances are equal" do
|
49
|
+
assert_equal command_name("foo").hash, command_name("foo").hash
|
50
|
+
end
|
51
|
+
|
44
52
|
test "is sorted by name" do
|
45
53
|
assert command_name("foo") > command_name("bar"), "expected 'foo' to be greater than 'bar'"
|
46
54
|
assert command_name("bar") < command_name("baz"), "expected 'bar' to be less than 'baz'"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'shellissimo/command_param'
|
3
|
+
|
4
|
+
include Shellissimo
|
5
|
+
|
6
|
+
class TestCommandParam < ShellissimoTestCase
|
7
|
+
test "can't be created without name" do
|
8
|
+
assert_raises ArgumentError, "command param name can't be blank" do
|
9
|
+
param(nil)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
test "can have a description" do
|
14
|
+
assert_equal "foo desc", param("foo", :noop, "foo desc").description
|
15
|
+
end
|
16
|
+
|
17
|
+
test "is always valid by default" do
|
18
|
+
assert param("foo").valid?(:literally_anything), "expected param to be valid by default"
|
19
|
+
end
|
20
|
+
|
21
|
+
test "param name is a symbol" do
|
22
|
+
assert_equal :foo, param("foo").name
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def param(*args)
|
28
|
+
CommandParam.new(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'shellissimo/command_param_validator'
|
3
|
+
|
4
|
+
include Shellissimo
|
5
|
+
|
6
|
+
class TestCommandParamValidator < ShellissimoTestCase
|
7
|
+
test "can have a description" do
|
8
|
+
assert_equal "foo desc", (validator("foo desc") {}).description
|
9
|
+
end
|
10
|
+
|
11
|
+
test "noop is always valid" do
|
12
|
+
assert noop_validator[:literally_anything], "expected param to be valid by default"
|
13
|
+
end
|
14
|
+
|
15
|
+
test "mandatory is not valid if nil" do
|
16
|
+
refute mandatory_validator[nil], "expected mandatory param not to be valid by if nil"
|
17
|
+
end
|
18
|
+
|
19
|
+
test "mandatory is valid if non-nil" do
|
20
|
+
assert mandatory_validator[1], "expected mandatory param to be valid by if non-nil"
|
21
|
+
end
|
22
|
+
|
23
|
+
test "allows combining validator with logical &" do
|
24
|
+
v = mandatory_validator & validator("custom") { |v| v.nil? || v == 1 }
|
25
|
+
refute v[nil], "expected mandatory validator to work"
|
26
|
+
refute v[2], "expected custom validator to work"
|
27
|
+
assert v[1], "expected both validators to work"
|
28
|
+
end
|
29
|
+
|
30
|
+
test "allows combining validator with logical |" do
|
31
|
+
v = validator("v1") { |v| v == 1 } | validator("v2") { |v| v == 2 }
|
32
|
+
assert v[1], "expected first custom validator to work"
|
33
|
+
assert v[2], "expected second custom validator to work"
|
34
|
+
refute v[0], "expected not to do whats not expected :)"
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def validator(description, &block)
|
40
|
+
CommandParamValidator.new(description, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
[:noop, :optioal, :mandatory].each do |kind|
|
44
|
+
define_method "#{kind}_validator" do
|
45
|
+
CommandParamValidator.public_send(kind)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'shellissimo/commands_collection'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
include Shellissimo
|
6
|
+
|
7
|
+
class TestCommandsCollection < ShellissimoTestCase
|
8
|
+
test "#find_by_name_or_alias returns command by name" do
|
9
|
+
assert_equal command("foo"), collection(command("foo")).find_by_name_or_alias("foo")
|
10
|
+
end
|
11
|
+
|
12
|
+
test "#[] returns command by name" do
|
13
|
+
assert_equal command("foo"), collection(command("foo"))["foo"]
|
14
|
+
end
|
15
|
+
|
16
|
+
test "is enumerable" do
|
17
|
+
c = collection(command("foo"), command("bar"))
|
18
|
+
assert_kind_of Enumerable, c
|
19
|
+
assert_equal [command("bar")], c.select { |c| c.name == "bar" }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def collection(*commands)
|
25
|
+
result = CommandsCollection.new
|
26
|
+
result.push *commands
|
27
|
+
end
|
28
|
+
|
29
|
+
def command(name)
|
30
|
+
OpenStruct.new(:name => name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -5,34 +5,25 @@ include Shellissimo
|
|
5
5
|
|
6
6
|
class TestDsl < ShellissimoTestCase
|
7
7
|
test ".command creates a command" do
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
test "#run inside .command sets command block" do
|
12
|
-
assert_equal :hello, fake_with_command_foo.commands.find_by_name_or_alias("foo").call
|
13
|
-
end
|
14
|
-
|
15
|
-
test "#shortcut inside .command sets command aliases" do
|
16
|
-
assert fake_with_command_foo.commands.find_by_name_or_alias("f"), "expected command 'foo' to be found by alias 'f'"
|
17
|
-
end
|
18
|
-
|
19
|
-
test "#description inside .command sets command description" do
|
20
|
-
assert_equal "foo description", fake_with_command_foo.commands.find_by_name_or_alias("foo").description
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def fake_with_command_foo
|
26
|
-
fake do
|
8
|
+
f = dsl do
|
27
9
|
command :foo do |c|
|
28
|
-
c.shortcut :f
|
29
|
-
c.description "foo description"
|
30
10
|
c.run { :hello }
|
31
11
|
end
|
32
12
|
end
|
13
|
+
assert f.commands["foo"], "expected command 'foo' to be defined"
|
33
14
|
end
|
34
15
|
|
35
|
-
|
16
|
+
test ".command yields a builder" do
|
17
|
+
builder = nil
|
18
|
+
dsl do
|
19
|
+
command(:foo) { |c| c.run {}; builder = c }
|
20
|
+
end
|
21
|
+
assert_instance_of DSL::CommandBuilder, builder
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def dsl(*args, &block)
|
36
27
|
Class.new do
|
37
28
|
include DSL
|
38
29
|
instance_eval(&block)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'shellissimo/input_parser'
|
3
3
|
require 'shellissimo/command'
|
4
|
+
require 'shellissimo/command_param'
|
4
5
|
|
5
6
|
include Shellissimo
|
6
7
|
|
@@ -24,9 +25,7 @@ class TestInputParser < ShellissimoTestCase
|
|
24
25
|
private
|
25
26
|
|
26
27
|
def commands
|
27
|
-
|
28
|
-
def cmds.find_by_name_or_alias(name); first; end
|
29
|
-
cmds
|
28
|
+
{ "foo" => Command.new("foo") { |*args| args } }
|
30
29
|
end
|
31
30
|
|
32
31
|
def parser
|
data/test/test_helper.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
2
3
|
|
3
|
-
|
4
|
+
lib = File.expand_path('../../lib', __FILE__)
|
5
|
+
$:.unshift lib
|
6
|
+
|
7
|
+
if ENV["TRAVIS"]
|
4
8
|
require 'simplecov'
|
5
|
-
SimpleCov.start
|
6
|
-
elsif ENV["TRAVIS"]
|
7
9
|
require 'coveralls'
|
8
|
-
Coveralls
|
10
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
11
|
+
SimpleCov.start do
|
12
|
+
add_filter "/test/"
|
13
|
+
end
|
14
|
+
Dir.glob(File.join(lib, "**", "*.rb")).each { |f| require f }
|
9
15
|
end
|
10
16
|
|
11
17
|
require 'minitest/unit'
|
12
|
-
require 'minitest/
|
18
|
+
require 'minitest/reporters'
|
13
19
|
|
14
|
-
|
20
|
+
MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new
|
15
21
|
|
16
22
|
class ShellissimoTestCase < MiniTest::Unit::TestCase
|
17
23
|
def self.test(name, &block)
|
metadata
CHANGED
@@ -1,64 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shellissimo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.0.1
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Vladimir Yarotsky
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-09 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
14
|
+
name: json
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
21
|
+
prerelease: false
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
23
|
requirements:
|
26
|
-
- -
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
27
32
|
- !ruby/object:Gem::Version
|
28
33
|
version: '0'
|
34
|
+
type: :development
|
29
35
|
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
30
41
|
- !ruby/object:Gem::Dependency
|
31
42
|
name: redcarpet
|
32
43
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
44
|
requirements:
|
35
|
-
- -
|
45
|
+
- - '>='
|
36
46
|
- !ruby/object:Gem::Version
|
37
47
|
version: '0'
|
38
|
-
type: :
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
39
50
|
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
none: false
|
41
51
|
requirements:
|
42
|
-
- -
|
52
|
+
- - '>='
|
43
53
|
- !ruby/object:Gem::Version
|
44
54
|
version: '0'
|
45
|
-
prerelease: false
|
46
55
|
- !ruby/object:Gem::Dependency
|
47
56
|
name: minitest
|
48
57
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
58
|
requirements:
|
51
|
-
- -
|
59
|
+
- - '>='
|
52
60
|
- !ruby/object:Gem::Version
|
53
61
|
version: '0'
|
54
62
|
type: :development
|
63
|
+
prerelease: false
|
55
64
|
version_requirements: !ruby/object:Gem::Requirement
|
56
|
-
none: false
|
57
65
|
requirements:
|
58
|
-
- -
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest-reporters
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
59
74
|
- !ruby/object:Gem::Version
|
60
75
|
version: '0'
|
76
|
+
type: :development
|
61
77
|
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
62
83
|
description:
|
63
84
|
email:
|
64
85
|
- vladimir.yarotsky@gmail.com
|
@@ -67,6 +88,7 @@ extensions: []
|
|
67
88
|
extra_rdoc_files: []
|
68
89
|
files:
|
69
90
|
- .gitignore
|
91
|
+
- .travis.yml
|
70
92
|
- Gemfile
|
71
93
|
- LICENSE.txt
|
72
94
|
- README.md
|
@@ -74,51 +96,59 @@ files:
|
|
74
96
|
- lib/shellissimo.rb
|
75
97
|
- lib/shellissimo/command.rb
|
76
98
|
- lib/shellissimo/command_name.rb
|
99
|
+
- lib/shellissimo/command_param.rb
|
100
|
+
- lib/shellissimo/command_param_validator.rb
|
101
|
+
- lib/shellissimo/commands_collection.rb
|
77
102
|
- lib/shellissimo/dsl.rb
|
78
103
|
- lib/shellissimo/dsl/command_builder.rb
|
104
|
+
- lib/shellissimo/dsl/command_param_builder.rb
|
79
105
|
- lib/shellissimo/error_handling.rb
|
106
|
+
- lib/shellissimo/help.rb
|
80
107
|
- lib/shellissimo/input_parser.rb
|
81
108
|
- lib/shellissimo/shell.rb
|
82
109
|
- lib/shellissimo/version.rb
|
83
110
|
- shellissimo.gemspec
|
111
|
+
- test/lib/shellissimo/dsl/test_command_builder.rb
|
112
|
+
- test/lib/shellissimo/dsl/test_command_param_builder.rb
|
84
113
|
- test/lib/shellissimo/test_command.rb
|
85
114
|
- test/lib/shellissimo/test_command_name.rb
|
115
|
+
- test/lib/shellissimo/test_command_param.rb
|
116
|
+
- test/lib/shellissimo/test_command_param_validator.rb
|
117
|
+
- test/lib/shellissimo/test_commands_collection.rb
|
86
118
|
- test/lib/shellissimo/test_dsl.rb
|
87
119
|
- test/lib/shellissimo/test_input_parser.rb
|
88
120
|
- test/test_helper.rb
|
89
121
|
homepage: https://github.com/v-yarotsky/shellissimo
|
90
122
|
licenses: []
|
123
|
+
metadata: {}
|
91
124
|
post_install_message:
|
92
125
|
rdoc_options: []
|
93
126
|
require_paths:
|
94
127
|
- lib
|
95
128
|
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
-
none: false
|
97
129
|
requirements:
|
98
|
-
- -
|
130
|
+
- - '>='
|
99
131
|
- !ruby/object:Gem::Version
|
100
|
-
segments:
|
101
|
-
- 0
|
102
|
-
hash: 1124256564094815538
|
103
132
|
version: '0'
|
104
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
134
|
requirements:
|
107
|
-
- -
|
135
|
+
- - '>='
|
108
136
|
- !ruby/object:Gem::Version
|
109
|
-
segments:
|
110
|
-
- 0
|
111
|
-
hash: 1124256564094815538
|
112
137
|
version: '0'
|
113
138
|
requirements: []
|
114
139
|
rubyforge_project:
|
115
|
-
rubygems_version:
|
140
|
+
rubygems_version: 2.0.3
|
116
141
|
signing_key:
|
117
|
-
specification_version:
|
142
|
+
specification_version: 4
|
118
143
|
summary: Minimalistic framework for constructing shell-like applications
|
119
144
|
test_files:
|
145
|
+
- test/lib/shellissimo/dsl/test_command_builder.rb
|
146
|
+
- test/lib/shellissimo/dsl/test_command_param_builder.rb
|
120
147
|
- test/lib/shellissimo/test_command.rb
|
121
148
|
- test/lib/shellissimo/test_command_name.rb
|
149
|
+
- test/lib/shellissimo/test_command_param.rb
|
150
|
+
- test/lib/shellissimo/test_command_param_validator.rb
|
151
|
+
- test/lib/shellissimo/test_commands_collection.rb
|
122
152
|
- test/lib/shellissimo/test_dsl.rb
|
123
153
|
- test/lib/shellissimo/test_input_parser.rb
|
124
154
|
- test/test_helper.rb
|