quickl 0.2.2 → 0.3.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.
- data/CHANGELOG.md +82 -0
- data/Gemfile.lock +14 -14
- data/bin/quickl +2 -2
- data/lib/quickl.rb +162 -2
- data/lib/quickl/command.rb +22 -32
- data/lib/quickl/command/builder.rb +3 -3
- data/lib/quickl/command/delegator.rb +22 -12
- data/lib/quickl/command/options.rb +29 -4
- data/lib/quickl/command/robustness.rb +5 -12
- data/lib/quickl/command/single.rb +4 -6
- data/lib/quickl/errors.rb +2 -2
- data/lib/quickl/version.rb +2 -2
- data/quickl.gemspec +4 -4
- data/quickl.noespec +13 -37
- data/spec/command/delegator/test_split_argv.rb +41 -0
- data/spec/command/{command_building_spec.rb → test_command_building.rb} +4 -4
- data/spec/command/{command_name_spec.rb → test_command_name.rb} +1 -6
- data/spec/command/{documentation_spec.rb → test_documentation.rb} +1 -1
- data/spec/command/{overview_spec.rb → test_overview.rb} +1 -5
- data/spec/command/test_parse_options.rb +112 -0
- data/spec/command/{requester_spec.rb → test_requester.rb} +1 -1
- data/spec/command/test_run.rb +40 -0
- data/spec/command/{subcommand_by_name_spec.rb → test_subcommand_by_name.rb} +3 -3
- data/spec/command/{subcommands_spec.rb → test_subcommands.rb} +8 -7
- data/spec/command/test_usage.rb +11 -0
- data/spec/mini_client.rb +36 -6
- data/spec/naming/test_command2module.rb +17 -0
- data/spec/naming/test_module2command.rb +21 -0
- data/spec/quickl/test_command_name.rb +16 -0
- data/spec/quickl/test_documentation.rb +32 -0
- data/spec/quickl/test_overview.rb +16 -0
- data/spec/quickl/test_parse_commandline_args.rb +52 -0
- data/spec/quickl/test_split_commandline_args.rb +39 -0
- data/spec/quickl/test_sub_command.rb +48 -0
- data/spec/quickl/test_super_command.rb +21 -0
- data/spec/quickl/test_usage.rb +16 -0
- data/spec/{command/robustness/valid_read_file_spec.rb → quickl/test_valid_read_file.rb} +4 -4
- data/spec/ruby_tools/fixtures.rb +1 -1
- data/spec/ruby_tools/{class_unqualified_name_spec.rb → test_class_unqualified_name.rb} +0 -0
- data/spec/ruby_tools/{extract_file_rdoc_spec.rb → test_extract_file_rdoc.rb} +0 -0
- data/spec/ruby_tools/{optional_args_block_call_spec.rb → test_optional_args_block.rb} +0 -0
- data/spec/ruby_tools/{parent_module_spec.rb → test_parent_module.rb} +0 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/{quickl_spec.rb → test_quickl.rb} +1 -1
- data/tasks/debug_mail.rake +1 -1
- data/tasks/spec_test.rake +2 -2
- data/tasks/unit_test.rake +2 -2
- data/templates/single.erb +1 -1
- metadata +96 -76
- data/spec/command/run_spec.rb +0 -22
- data/spec/command/usage_spec.rb +0 -16
- data/spec/naming/command2module_spec.rb +0 -17
- data/spec/naming/module2command_spec.rb +0 -21
@@ -1,14 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
module Quickl
|
3
3
|
describe "Command::subcommand_by_name /" do
|
4
4
|
|
5
5
|
specify "when called on single command names" do
|
6
|
-
MiniClient.subcommand_by_name("help").should
|
6
|
+
MiniClient.subcommand_by_name("help").should eq(MiniClient::Help)
|
7
7
|
MiniClient.subcommand_by_name("noway").should be_nil
|
8
8
|
end
|
9
9
|
|
10
10
|
specify "when called on complex command names" do
|
11
|
-
MiniClient.subcommand_by_name("say:hello").should
|
11
|
+
MiniClient.subcommand_by_name("say:hello").should eq(MiniClient::Say::Hello)
|
12
12
|
end
|
13
13
|
|
14
14
|
end # Command::command_name
|
@@ -1,23 +1,24 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
module Quickl
|
3
3
|
describe "Command::subcommands /" do
|
4
4
|
|
5
5
|
it "should return installed commands in an array" do
|
6
|
-
MiniClient.subcommands.should
|
6
|
+
MiniClient.subcommands.should eq([
|
7
7
|
MiniClient::Help,
|
8
8
|
MiniClient::Say,
|
9
9
|
MiniClient::Requester,
|
10
|
-
]
|
11
|
-
MiniClient::Say.subcommands.should
|
10
|
+
])
|
11
|
+
MiniClient::Say.subcommands.should eq([
|
12
12
|
MiniClient::Say::Hello,
|
13
13
|
MiniClient::Say::Goodbye,
|
14
|
-
|
14
|
+
MiniClient::Say::Args
|
15
|
+
])
|
15
16
|
end
|
16
17
|
|
17
18
|
it "should take care of the command_parent= in command builder" do
|
18
|
-
MiniClient::Requester.subcommands.should
|
19
|
+
MiniClient::Requester.subcommands.should eq([
|
19
20
|
MiniClient::Factored
|
20
|
-
]
|
21
|
+
])
|
21
22
|
end
|
22
23
|
|
23
24
|
end # Command::subcommand
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Quickl
|
3
|
+
describe "Command::usage /" do
|
4
|
+
|
5
|
+
it "should be installed from inline rdoc" do
|
6
|
+
MiniClient::Say::Hello.usage.should eq("mini-client say:hello")
|
7
|
+
MiniClient::Say::Goodbye.usage.should eq("mini-client say:goodbye")
|
8
|
+
end
|
9
|
+
|
10
|
+
end # Command::usage
|
11
|
+
end # module Quickl
|
data/spec/mini_client.rb
CHANGED
@@ -2,7 +2,17 @@
|
|
2
2
|
# MiniClient main command
|
3
3
|
#
|
4
4
|
class MiniClient < Quickl::Delegator(__FILE__, __LINE__)
|
5
|
+
|
6
|
+
# Is verbose?
|
7
|
+
attr_accessor :verbose
|
5
8
|
|
9
|
+
options do |opt|
|
10
|
+
@verbose = false
|
11
|
+
opt.on("-v", "--[no-]verbose") do |val|
|
12
|
+
self.verbose = val
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
6
16
|
#
|
7
17
|
# Print help
|
8
18
|
#
|
@@ -14,7 +24,7 @@ class MiniClient < Quickl::Delegator(__FILE__, __LINE__)
|
|
14
24
|
#
|
15
25
|
class Help < Quickl::Command(__FILE__, __LINE__)
|
16
26
|
|
17
|
-
def execute(
|
27
|
+
def execute(args)
|
18
28
|
:help
|
19
29
|
end
|
20
30
|
|
@@ -34,7 +44,7 @@ class MiniClient < Quickl::Delegator(__FILE__, __LINE__)
|
|
34
44
|
#
|
35
45
|
class Hello < Quickl::Command(__FILE__, __LINE__)
|
36
46
|
|
37
|
-
def execute(
|
47
|
+
def execute(args)
|
38
48
|
:hello
|
39
49
|
end
|
40
50
|
|
@@ -48,12 +58,32 @@ class MiniClient < Quickl::Delegator(__FILE__, __LINE__)
|
|
48
58
|
#
|
49
59
|
class Goodbye < Quickl::Command(__FILE__, __LINE__)
|
50
60
|
|
51
|
-
def execute(
|
61
|
+
def execute(args)
|
52
62
|
:goodbye
|
53
63
|
end
|
54
64
|
|
55
65
|
end # class Goodbye
|
56
66
|
|
67
|
+
#
|
68
|
+
# Say the args
|
69
|
+
#
|
70
|
+
# SYNOPSIS
|
71
|
+
# #{MiniClient.command_name} say:args
|
72
|
+
#
|
73
|
+
class Args < Quickl::Command(__FILE__, __LINE__)
|
74
|
+
|
75
|
+
options do |opt|
|
76
|
+
opt.on('-i', '--ioption'){}
|
77
|
+
opt.on('-j', '--joption'){}
|
78
|
+
opt.on('-k', '--koption'){}
|
79
|
+
end
|
80
|
+
|
81
|
+
def run(args, sep_support = nil)
|
82
|
+
parse_options(args, sep_support)
|
83
|
+
end
|
84
|
+
|
85
|
+
end # class Args
|
86
|
+
|
57
87
|
end # class Say
|
58
88
|
|
59
89
|
#
|
@@ -64,7 +94,7 @@ class MiniClient < Quickl::Delegator(__FILE__, __LINE__)
|
|
64
94
|
#
|
65
95
|
class Requester < Quickl::Command(__FILE__, __LINE__)
|
66
96
|
|
67
|
-
def execute(
|
97
|
+
def execute(args)
|
68
98
|
requester
|
69
99
|
end
|
70
100
|
|
@@ -87,10 +117,10 @@ class MiniClient < Quickl::Delegator(__FILE__, __LINE__)
|
|
87
117
|
#
|
88
118
|
class Factored < Factor(__FILE__, __LINE__, :hello)
|
89
119
|
|
90
|
-
def execute(
|
120
|
+
def execute(args)
|
91
121
|
self.class.instance_eval{ @factored_arg }
|
92
122
|
end
|
93
123
|
|
94
124
|
end
|
95
125
|
|
96
|
-
end # module MiniClient
|
126
|
+
end # module MiniClient
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Quickl
|
3
|
+
describe "Naming::command2module /" do
|
4
|
+
include Naming
|
5
|
+
|
6
|
+
it "should capitalize first char" do
|
7
|
+
command2module("say").should eq("Say")
|
8
|
+
command2module(:say).should eq(:Say)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should capitalize support dashes" do
|
12
|
+
command2module("say-hello").should eq("SayHello")
|
13
|
+
command2module(:"say-hello").should eq(:SayHello)
|
14
|
+
end
|
15
|
+
|
16
|
+
end # module Quickl
|
17
|
+
end # module Quickl
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Quickl
|
3
|
+
describe "Naming::module2command /" do
|
4
|
+
include Naming
|
5
|
+
|
6
|
+
it "should uncapitalize first char" do
|
7
|
+
module2command("Say").should eq("say")
|
8
|
+
module2command(:Say).should eq(:say)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should uncapitalize and introduce dashes" do
|
12
|
+
module2command("SayHello").should eq("say-hello")
|
13
|
+
module2command(:"SayHello").should eq(:"say-hello")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should support taking modules as argument" do
|
17
|
+
module2command(Quickl::Command).should eq("command")
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module Quickl
|
21
|
+
end # module Quickl
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
describe "Quickl#command_name" do
|
3
|
+
|
4
|
+
subject{ Quickl.command_name(cmd) }
|
5
|
+
|
6
|
+
describe "on a command class" do
|
7
|
+
let(:cmd){ MiniClient::Say::Hello }
|
8
|
+
it{ should eq("hello") }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "on a command instance" do
|
12
|
+
let(:cmd){ MiniClient::Say::Hello.new }
|
13
|
+
it{ should eq("hello") }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
$hello_doc = <<EOF
|
2
|
+
|
3
|
+
Say hello to the user whose name is requested on the standard input
|
4
|
+
|
5
|
+
SYNOPSIS
|
6
|
+
mini-client say:hello
|
7
|
+
|
8
|
+
DESCRIPTION
|
9
|
+
And an explanation here
|
10
|
+
on multiple lines with replacement: hello
|
11
|
+
|
12
|
+
EOF
|
13
|
+
require "spec_helper"
|
14
|
+
describe "Quickl#documentation" do
|
15
|
+
|
16
|
+
subject{ Quickl.documentation(cmd) }
|
17
|
+
|
18
|
+
describe "on a command class" do
|
19
|
+
let(:cmd){ MiniClient::Say::Hello }
|
20
|
+
it{ should eq($hello_doc) }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "on a command instance" do
|
24
|
+
let(:cmd){ MiniClient::Say::Hello.new }
|
25
|
+
it{ should eq($hello_doc) }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be aliased as help" do
|
29
|
+
Quickl.help(MiniClient::Say::Hello).should eq($hello_doc)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
describe "Quickl#overview" do
|
3
|
+
|
4
|
+
subject{ Quickl.overview(cmd) }
|
5
|
+
|
6
|
+
describe "on a command class" do
|
7
|
+
let(:cmd){ MiniClient::Help }
|
8
|
+
it{ should eq("Print help") }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "on a command instance" do
|
12
|
+
let(:cmd){ MiniClient::Help.new }
|
13
|
+
it{ should eq("Print help") }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe "Quickl.parse_commandline_args" do
|
3
|
+
|
4
|
+
subject{ Quickl.parse_commandline_args(args) }
|
5
|
+
|
6
|
+
describe "on empty string" do
|
7
|
+
let(:args){ "" }
|
8
|
+
it { should eq([]) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "on pseudo empty string" do
|
12
|
+
let(:args){ " " }
|
13
|
+
it { should eq([]) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "on a single arg" do
|
17
|
+
let(:args){ "--text" }
|
18
|
+
it { should eq(["--text"]) }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "on a multiple args" do
|
22
|
+
let(:args){ "--text --size=10" }
|
23
|
+
it { should eq(["--text", "--size=10"]) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "on single quoted arg" do
|
27
|
+
let(:args){ "'hello'" }
|
28
|
+
it { should eq(["hello"]) }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "on single quoted arg with spacing" do
|
32
|
+
let(:args){ "'hello the world'" }
|
33
|
+
it { should eq(["hello the world"]) }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "on double quoted arg" do
|
37
|
+
let(:args){ '"hello"' }
|
38
|
+
it { should eq(["hello"]) }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "on double quoted arg with spacing" do
|
42
|
+
let(:args){ "'hello the world'" }
|
43
|
+
it { should eq(['hello the world']) }
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "on typical example" do
|
47
|
+
let(:args){ %q{--verbose 'hello the world' -g -Ilib --term='none'}}
|
48
|
+
it{ should eq(["--verbose", 'hello the world', "-g", "-Ilib", "--term='none'"]) }
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe "Quickl.split_commandline_args" do
|
3
|
+
|
4
|
+
subject{ Quickl.split_commandline_args(args) }
|
5
|
+
|
6
|
+
describe "on an empty array" do
|
7
|
+
let(:args){ %w{} }
|
8
|
+
it { should eq([%w{}]) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "without an option separator" do
|
12
|
+
let(:args){ %w{hello world} }
|
13
|
+
it { should eq([%w{hello world}]) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with an option at start" do
|
17
|
+
let(:args){ %w{-- hello world} }
|
18
|
+
it { should eq([%w{}, %w{hello world}]) }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "with an option at end" do
|
22
|
+
let(:args){ %w{hello world --} }
|
23
|
+
it { should eq([%w{hello world}, %w{}]) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "with an option separator in the middle" do
|
27
|
+
let(:args){ %w{hello -- world} }
|
28
|
+
it { should eq([%w{hello}, %w{world}]) }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "on a complex example" do
|
32
|
+
let(:args){ %w{-- hello -- hello2 hello3 -- x --} }
|
33
|
+
let(:expected){[
|
34
|
+
%w{}, %w{hello}, %w{hello2 hello3}, %w{x}, %w{}
|
35
|
+
]}
|
36
|
+
it { should eq(expected) }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe "Quickl.sub_command(!)" do
|
3
|
+
|
4
|
+
describe "non bang version" do
|
5
|
+
subject{ Quickl.sub_command(cmd, name) }
|
6
|
+
|
7
|
+
describe "on a command class with existing sub" do
|
8
|
+
let(:cmd){ MiniClient }
|
9
|
+
let(:name){ "say:hello" }
|
10
|
+
it{ should eq(MiniClient::Say::Hello) }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "on a command instance with existing sub" do
|
14
|
+
let(:cmd){ MiniClient.new }
|
15
|
+
let(:name){ "say:hello" }
|
16
|
+
it{ should eq(MiniClient::Say::Hello) }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "when no such existing sub" do
|
20
|
+
let(:cmd){ MiniClient.new }
|
21
|
+
let(:name){ "say:wouwouwou" }
|
22
|
+
it{ should be_nil }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "the bang version" do
|
27
|
+
subject{ Quickl.sub_command!(cmd, name) }
|
28
|
+
|
29
|
+
describe "on a command class with existing sub" do
|
30
|
+
let(:cmd){ MiniClient }
|
31
|
+
let(:name){ "say:hello" }
|
32
|
+
it{ should eq(MiniClient::Say::Hello) }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "on a command instance with existing sub" do
|
36
|
+
let(:cmd){ MiniClient.new }
|
37
|
+
let(:name){ "say:hello" }
|
38
|
+
it{ should eq(MiniClient::Say::Hello) }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "when no such existing sub" do
|
42
|
+
let(:cmd){ MiniClient.new }
|
43
|
+
let(:name){ "say:wouwouwou" }
|
44
|
+
specify{ lambda{subject}.should raise_error(Quickl::NoSuchCommand) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe "Quickl.super_command" do
|
3
|
+
|
4
|
+
subject{ Quickl.super_command(cmd) }
|
5
|
+
|
6
|
+
describe "on a command class" do
|
7
|
+
let(:cmd){ MiniClient::Say::Hello }
|
8
|
+
it{ should eq(MiniClient::Say) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "on a command instance" do
|
12
|
+
let(:cmd){ MiniClient::Say::Hello.new }
|
13
|
+
it{ should eq(MiniClient::Say) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "with no super command" do
|
17
|
+
let(:cmd){ MiniClient }
|
18
|
+
it{ should be_nil }
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
describe "Quickl#usage" do
|
3
|
+
|
4
|
+
subject{ Quickl.usage(cmd) }
|
5
|
+
|
6
|
+
describe "on a command class" do
|
7
|
+
let(:cmd){ MiniClient::Say::Hello }
|
8
|
+
it{ should eq("mini-client say:hello") }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "on a command instance" do
|
12
|
+
let(:cmd){ MiniClient::Say::Hello.new }
|
13
|
+
it{ should eq("mini-client say:hello") }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|