ronin 1.4.1 → 1.5.0.rc1
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/.document +1 -0
- data/.gitignore +1 -0
- data/ChangeLog.md +38 -1
- data/Gemfile +10 -10
- data/README.md +1 -1
- data/Rakefile +13 -2
- data/bin/ronin-net-proxy +25 -0
- data/gemspec.yml +21 -2
- data/lib/bond/completions/ronin.rb +16 -5
- data/lib/ronin/arch.rb +5 -5
- data/lib/ronin/auto_load.rb +22 -1
- data/lib/ronin/campaign.rb +1 -1
- data/lib/ronin/database/database.rb +36 -25
- data/lib/ronin/installation.rb +2 -2
- data/lib/ronin/model/model.rb +5 -6
- data/lib/ronin/model/types/description.rb +0 -3
- data/lib/ronin/os.rb +2 -2
- data/lib/ronin/password.rb +1 -1
- data/lib/ronin/repository.rb +6 -6
- data/lib/ronin/script/path.rb +1 -2
- data/lib/ronin/spec/database.rb +16 -4
- data/lib/ronin/ui/cli/cli.rb +1 -1
- data/lib/ronin/ui/cli/command.rb +50 -7
- data/lib/ronin/ui/cli/commands/console.rb +15 -6
- data/lib/ronin/ui/cli/commands/creds.rb +1 -1
- data/lib/ronin/ui/cli/commands/database.rb +41 -29
- data/lib/ronin/ui/cli/commands/emails.rb +20 -15
- data/lib/ronin/ui/cli/commands/help.rb +18 -5
- data/lib/ronin/ui/cli/commands/hosts.rb +34 -27
- data/lib/ronin/ui/cli/commands/install.rb +21 -4
- data/lib/ronin/ui/cli/commands/ips.rb +34 -23
- data/lib/ronin/ui/cli/commands/net/proxy.rb +403 -0
- data/lib/ronin/ui/cli/commands/repos.rb +4 -4
- data/lib/ronin/ui/cli/commands/uninstall.rb +10 -0
- data/lib/ronin/ui/cli/commands/update.rb +11 -1
- data/lib/ronin/ui/cli/commands/urls.rb +39 -30
- data/lib/ronin/ui/cli/commands/wordlist.rb +11 -1
- data/lib/ronin/ui/console.rb +1 -0
- data/lib/ronin/ui/console/commands.rb +16 -98
- data/lib/ronin/ui/console/shell.rb +184 -0
- data/lib/ronin/url.rb +3 -3
- data/lib/ronin/url_scheme.rb +3 -3
- data/lib/ronin/version.rb +1 -1
- data/man/ronin-campaigns.1.md +78 -0
- data/man/ronin-console.1.md +72 -0
- data/man/ronin-creds.1.md +66 -0
- data/man/ronin-database.1.md +82 -0
- data/man/ronin-emails.1.md +72 -0
- data/man/ronin-exec.1.md +49 -0
- data/man/ronin-help.1.md +34 -0
- data/man/ronin-hosts.1.md +78 -0
- data/man/ronin-install.1.md +79 -0
- data/man/ronin-ips.1.md +81 -0
- data/man/ronin-net-proxy.1.md +86 -0
- data/man/ronin-repos.1.md +77 -0
- data/man/ronin-uninstall.1.md +67 -0
- data/man/ronin-update.1.md +67 -0
- data/man/ronin-urls.1.md +84 -0
- data/man/ronin-wordlist.1.md +53 -0
- data/man/ronin.1.md +26 -0
- data/ronin.gemspec +38 -109
- data/spec/installation_spec.rb +2 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/ui/cli/classes/test_command.rb +7 -0
- data/spec/ui/cli/command_spec.rb +235 -7
- metadata +217 -96
@@ -0,0 +1,67 @@
|
|
1
|
+
# ronin-update 1 "April 2012" Ronin "User Manuals"
|
2
|
+
|
3
|
+
## SYNOPSIS
|
4
|
+
|
5
|
+
`ronin update` [*options*] [*REPO*]
|
6
|
+
|
7
|
+
## DESCRIPTION
|
8
|
+
|
9
|
+
Updates Ronin Repositories.
|
10
|
+
|
11
|
+
## ARGUMENTS
|
12
|
+
|
13
|
+
*REPO*
|
14
|
+
The name of the Repository to update.
|
15
|
+
|
16
|
+
## OPTIONS
|
17
|
+
|
18
|
+
`-v`, `--[no-]verbose`
|
19
|
+
Enable verbose output.
|
20
|
+
|
21
|
+
`-q`, `--[no-]quiet`
|
22
|
+
Disable verbose output.
|
23
|
+
|
24
|
+
`--[no-]silent`
|
25
|
+
Silence all output.
|
26
|
+
|
27
|
+
`--[no-]color`
|
28
|
+
Enables color output.
|
29
|
+
|
30
|
+
## EXAMPLES
|
31
|
+
|
32
|
+
`ronin update repo`
|
33
|
+
Updates the repository with with the name `repo`.
|
34
|
+
|
35
|
+
`ronin update repo@github.com`
|
36
|
+
Updates the repository with the name `repo` and from `github.com`.
|
37
|
+
|
38
|
+
## FILES
|
39
|
+
|
40
|
+
*~/.ronin/*
|
41
|
+
Ronin configuration directory.
|
42
|
+
|
43
|
+
*~/.ronin/repos*
|
44
|
+
Installation directory for Ronin Repositories.
|
45
|
+
|
46
|
+
*~/.ronin/database.log*
|
47
|
+
Database log.
|
48
|
+
|
49
|
+
*~/.ronin/database.sqlite3*
|
50
|
+
The default sqlite3 Database file.
|
51
|
+
|
52
|
+
*~/.ronin/database.yml*
|
53
|
+
Optional Database configuration.
|
54
|
+
|
55
|
+
## ENVIRONMENT
|
56
|
+
|
57
|
+
HOME
|
58
|
+
Specifies the home directory of the user. Ronin will search for the `.ronin`
|
59
|
+
configuration directory within the home directory.
|
60
|
+
|
61
|
+
## AUTHOR
|
62
|
+
|
63
|
+
Postmodern <postmodern.mod3@gmail.com>
|
64
|
+
|
65
|
+
## SEE ALSO
|
66
|
+
|
67
|
+
ronin-install(1) ronin-repos(1) ronin-uninstall(1)
|
data/man/ronin-urls.1.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# ronin-urls 1 "April 2012" Ronin "User Manuals"
|
2
|
+
|
3
|
+
## SYNOPSIS
|
4
|
+
|
5
|
+
`ronin urls` [*options*]
|
6
|
+
|
7
|
+
## DESCRIPTION
|
8
|
+
|
9
|
+
Manages URLs.
|
10
|
+
|
11
|
+
## OPTIONS
|
12
|
+
|
13
|
+
`-v`, `--[no-]verbose`
|
14
|
+
Enable verbose output.
|
15
|
+
|
16
|
+
`-q`, `--[no-]quiet`
|
17
|
+
Disable verbose output.
|
18
|
+
|
19
|
+
`--[no-]silent`
|
20
|
+
Silence all output.
|
21
|
+
|
22
|
+
`--[no-]color`
|
23
|
+
Enables color output.
|
24
|
+
|
25
|
+
`-D`, `--database` *URI*
|
26
|
+
The database to URI (`mysql://user:password@host/ronin`).
|
27
|
+
|
28
|
+
`--[no-]csv`
|
29
|
+
CSV output.
|
30
|
+
|
31
|
+
`--[no-]xml`
|
32
|
+
XML output.
|
33
|
+
|
34
|
+
`--[no-]yaml`
|
35
|
+
YAML output.
|
36
|
+
|
37
|
+
`--[no-]json`
|
38
|
+
JSON output.
|
39
|
+
|
40
|
+
`-i`, `--import` *FILE*
|
41
|
+
Imports HostNames from the FILE.
|
42
|
+
|
43
|
+
`--[no-]http`
|
44
|
+
Searches for `http://` URLs.
|
45
|
+
|
46
|
+
`--[no-]https`
|
47
|
+
Searches for `https://` URLs.
|
48
|
+
|
49
|
+
`-H`, `--hosts` *HOST* [...]
|
50
|
+
Searches for URLs with the given HOST name(s).
|
51
|
+
|
52
|
+
`-p`, `--with-ports` *PORT* [...]
|
53
|
+
Searches for URLs associated with the PORT(s).
|
54
|
+
|
55
|
+
`-d`, `--directory` *DIRECTORY*
|
56
|
+
Searches for URLs sharing the DIRECTORY.
|
57
|
+
|
58
|
+
`-q`, `--with-query-param` *NAME* [...]
|
59
|
+
Searches for URLs containing the query-param NAME.
|
60
|
+
|
61
|
+
`-Q`, `--with-query-value` *VALUE* [...]
|
62
|
+
Searches for URLs containing the query-param VALUE.
|
63
|
+
|
64
|
+
`-l`, `--[no-]list`
|
65
|
+
Lists the HostNames.
|
66
|
+
|
67
|
+
## FILES
|
68
|
+
|
69
|
+
*~/.ronin/*
|
70
|
+
Ronin configuration directory.
|
71
|
+
|
72
|
+
*~/.ronin/database.log*
|
73
|
+
Database log.
|
74
|
+
|
75
|
+
*~/.ronin/database.sqlite3*
|
76
|
+
The default sqlite3 Database file.
|
77
|
+
|
78
|
+
*~/.ronin/database.yml*
|
79
|
+
Optional Database configuration.
|
80
|
+
|
81
|
+
## AUTHOR
|
82
|
+
|
83
|
+
Postmodern <postmodern.mod3@gmail.com>
|
84
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# ronin-wordlist 1 "April 2012" Ronin "User Manuals"
|
2
|
+
|
3
|
+
## SYNOPSIS
|
4
|
+
|
5
|
+
`ronin wordlist` [*options*] [*TEMPLATE*]
|
6
|
+
|
7
|
+
## DESCRIPTION
|
8
|
+
|
9
|
+
Builds and/or mutates Wordlists.
|
10
|
+
|
11
|
+
## ARGUMENTS
|
12
|
+
|
13
|
+
*TEMPLATE*
|
14
|
+
Options word template to generate the wordlist with (`alpha:7 numeric:1-3`).
|
15
|
+
|
16
|
+
## OPTIONS
|
17
|
+
|
18
|
+
`-v`, `--[no-]verbose`
|
19
|
+
Enable verbose output.
|
20
|
+
|
21
|
+
`-q`, `--[no-]quiet`
|
22
|
+
Disable verbose output.
|
23
|
+
|
24
|
+
`--[no-]silent`
|
25
|
+
Silence all output.
|
26
|
+
|
27
|
+
`--[no-]color`
|
28
|
+
Enables color output.
|
29
|
+
|
30
|
+
`-i`, `--input` *FILE*
|
31
|
+
The input text FILE to parse.
|
32
|
+
|
33
|
+
`-o`, `--output` *PATH*
|
34
|
+
The output PATH to write the wordlist to.
|
35
|
+
|
36
|
+
`-m`, `--mutations` *STRING*:*SUBSTITUTE*
|
37
|
+
Mutations to apply to the words. If STRING is found within a word, it will be
|
38
|
+
replaced with SUBSTITUTE.
|
39
|
+
|
40
|
+
## EXAMPLES
|
41
|
+
|
42
|
+
`ronin wordlist alpha:7 numeric:1-3`
|
43
|
+
Enumerates through every possible word, with each word beginning with seven
|
44
|
+
alphabetic characters and ending in 1-3 numeric characters.
|
45
|
+
|
46
|
+
`ronin wordlist --input text.txt -m e:3 -m a:@ -m o:0`
|
47
|
+
Builds a wordlist from a text file, applying basic "leet-speak" mutation rules
|
48
|
+
to each word.
|
49
|
+
|
50
|
+
## AUTHOR
|
51
|
+
|
52
|
+
Postmodern <postmodern.mod3@gmail.com>
|
53
|
+
|
data/man/ronin.1.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# ronin 1 "April 2012" Ronin "User Manuals"
|
2
|
+
|
3
|
+
## SYNOPSIS
|
4
|
+
|
5
|
+
`ronin` [*COMMAND*] [*options*]
|
6
|
+
|
7
|
+
## DESCRIPTION
|
8
|
+
|
9
|
+
Runs a Ronin COMMAND or the starts Ronin Console.
|
10
|
+
|
11
|
+
## ARGUMENTS
|
12
|
+
|
13
|
+
*COMMAND*
|
14
|
+
The Ronin command to execute.
|
15
|
+
|
16
|
+
## OPTIONS
|
17
|
+
|
18
|
+
Additional options for the COMMAND or the Ronin Console.
|
19
|
+
|
20
|
+
## AUTHOR
|
21
|
+
|
22
|
+
Postmodern <postmodern.mod3@gmail.com>
|
23
|
+
|
24
|
+
## SEE ALSO
|
25
|
+
|
26
|
+
ronin-console(1)
|
data/ronin.gemspec
CHANGED
@@ -2,130 +2,59 @@
|
|
2
2
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
|
-
Gem::Specification.new do |
|
6
|
-
|
7
|
-
lib_dir = File.join(root,'lib')
|
8
|
-
files = if File.directory?('.git')
|
9
|
-
`git ls-files`.split($/)
|
10
|
-
elsif File.directory?('.hg')
|
11
|
-
`hg manifest`.split($/)
|
12
|
-
elsif File.directory?('.svn')
|
13
|
-
`svn ls -R`.split($/).select { |path| File.file?(path) }
|
14
|
-
else
|
15
|
-
Dir['{**/}{.*,*}'].select { |path| File.file?(path) }
|
16
|
-
end
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gemspec = YAML.load_file('gemspec.yml')
|
17
7
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
when String
|
23
|
-
(files & Dir[paths])
|
24
|
-
end
|
25
|
-
}
|
26
|
-
|
27
|
-
version = {
|
28
|
-
:file => 'ronin/version',
|
29
|
-
:constant => 'Ronin::VERSION'
|
30
|
-
}
|
31
|
-
|
32
|
-
defaults = {
|
33
|
-
'name' => File.basename(root),
|
34
|
-
'files' => files,
|
35
|
-
'executables' => filter_files['bin/*'].map { |path| File.basename(path) },
|
36
|
-
'test_files' => filter_files['{test/{**/}*_test.rb,spec/{**/}*_spec.rb}'],
|
37
|
-
'extra_doc_files' => filter_files['*.{txt,rdoc,md,markdown,tt,textile}'],
|
38
|
-
}
|
8
|
+
gem.name = gemspec.fetch('name')
|
9
|
+
gem.version = gemspec.fetch('version') do
|
10
|
+
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
39
12
|
|
40
|
-
|
13
|
+
require 'ronin/version'
|
14
|
+
Ronin::VERSION
|
15
|
+
end
|
41
16
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
17
|
+
gem.summary = gemspec['summary']
|
18
|
+
gem.description = gemspec['description']
|
19
|
+
gem.licenses = Array(gemspec['license'])
|
20
|
+
gem.authors = Array(gemspec['authors'])
|
21
|
+
gem.email = gemspec['email']
|
22
|
+
gem.homepage = gemspec['homepage']
|
47
23
|
|
48
|
-
|
49
|
-
eval(version[:constant])
|
50
|
-
end
|
24
|
+
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
51
25
|
|
52
|
-
|
53
|
-
|
26
|
+
gem.files = `git ls-files`.split($/)
|
27
|
+
gem.files = glob[gemspec['files']] if gemspec['files']
|
54
28
|
|
55
|
-
|
56
|
-
|
57
|
-
gemspec.licenses = metadata['license']
|
58
|
-
when String
|
59
|
-
gemspec.license = metadata['license']
|
29
|
+
gem.executables = gemspec.fetch('executables') do
|
30
|
+
glob['bin/*'].map { |path| File.basename(path) }
|
60
31
|
end
|
32
|
+
gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
|
61
33
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
when String
|
66
|
-
gemspec.author = metadata['authors']
|
67
|
-
end
|
68
|
-
|
69
|
-
gemspec.email = metadata['email']
|
70
|
-
gemspec.homepage = metadata['homepage']
|
34
|
+
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
35
|
+
gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
|
36
|
+
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
71
37
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
when String
|
76
|
-
gemspec.require_path = metadata['require_paths']
|
77
|
-
end
|
38
|
+
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
39
|
+
%w[ext lib].select { |dir| File.directory?(dir) }
|
40
|
+
})
|
78
41
|
|
79
|
-
|
42
|
+
gem.requirements = gemspec['requirements']
|
43
|
+
gem.required_ruby_version = gemspec['required_ruby_version']
|
44
|
+
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
45
|
+
gem.post_install_message = gemspec['post_install_message']
|
80
46
|
|
81
|
-
|
82
|
-
gemspec.extensions = metadata['extensions']
|
83
|
-
|
84
|
-
if Gem::VERSION < '1.7.'
|
85
|
-
gemspec.default_executable = gemspec.executables.first
|
86
|
-
end
|
87
|
-
|
88
|
-
gemspec.test_files = filter_files[metadata['test_files']]
|
89
|
-
|
90
|
-
unless gemspec.files.include?('.document')
|
91
|
-
gemspec.extra_rdoc_files = metadata['extra_doc_files']
|
92
|
-
end
|
93
|
-
|
94
|
-
gemspec.post_install_message = metadata['post_install_message']
|
95
|
-
gemspec.requirements = metadata['requirements']
|
96
|
-
|
97
|
-
if gemspec.respond_to?(:required_ruby_version=)
|
98
|
-
gemspec.required_ruby_version = metadata['required_ruby_version']
|
99
|
-
end
|
100
|
-
|
101
|
-
if gemspec.respond_to?(:required_rubygems_version=)
|
102
|
-
gemspec.required_rubygems_version = metadata['required_rubygems_version']
|
103
|
-
end
|
104
|
-
|
105
|
-
parse_versions = lambda { |versions|
|
106
|
-
case versions
|
107
|
-
when Array
|
108
|
-
versions.map { |v| v.to_s }
|
109
|
-
when String
|
110
|
-
versions.split(/,\s*/)
|
111
|
-
end
|
112
|
-
}
|
113
|
-
|
114
|
-
if metadata['dependencies']
|
115
|
-
metadata['dependencies'].each do |name,versions|
|
116
|
-
gemspec.add_dependency(name,parse_versions[versions])
|
117
|
-
end
|
118
|
-
end
|
47
|
+
split = lambda { |string| string.split(/,\s*/) }
|
119
48
|
|
120
|
-
if
|
121
|
-
|
122
|
-
|
49
|
+
if gemspec['dependencies']
|
50
|
+
gemspec['dependencies'].each do |name,versions|
|
51
|
+
gem.add_dependency(name,split[versions])
|
123
52
|
end
|
124
53
|
end
|
125
54
|
|
126
|
-
if
|
127
|
-
|
128
|
-
|
55
|
+
if gemspec['development_dependencies']
|
56
|
+
gemspec['development_dependencies'].each do |name,versions|
|
57
|
+
gem.add_development_dependency(name,split[versions])
|
129
58
|
end
|
130
59
|
end
|
131
60
|
end
|
data/spec/installation_spec.rb
CHANGED
@@ -23,6 +23,7 @@ describe Installation do
|
|
23
23
|
hosts.rb
|
24
24
|
install.rb
|
25
25
|
ips.rb
|
26
|
+
net/proxy.rb
|
26
27
|
repos.rb
|
27
28
|
update.rb
|
28
29
|
urls.rb
|
@@ -32,7 +33,7 @@ describe Installation do
|
|
32
33
|
}
|
33
34
|
|
34
35
|
describe "each_file" do
|
35
|
-
let(:pattern) { File.join(directory,'*.rb') }
|
36
|
+
let(:pattern) { File.join(directory,'**','*.rb') }
|
36
37
|
let(:expected) { files.map { |name| File.join(directory,name) } }
|
37
38
|
|
38
39
|
it "should enumerate over the files which match a glob pattern" do
|
data/spec/spec_helper.rb
CHANGED
@@ -6,9 +6,11 @@ require 'model/models/described_model'
|
|
6
6
|
require 'model/models/licensed_model'
|
7
7
|
require 'model/models/named_model'
|
8
8
|
require 'model/models/titled_model'
|
9
|
+
require 'classes/my_script'
|
9
10
|
require 'helpers/repositories'
|
10
11
|
|
11
12
|
require 'ronin/spec/database'
|
13
|
+
require 'ronin/spec/ui/output'
|
12
14
|
|
13
15
|
include Ronin
|
14
16
|
|
data/spec/ui/cli/command_spec.rb
CHANGED
@@ -6,8 +6,241 @@ require 'ui/cli/classes/test_command'
|
|
6
6
|
describe UI::CLI::Command do
|
7
7
|
subject { TestCommand }
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
describe "command_name" do
|
10
|
+
it "should be derived from the Class name" do
|
11
|
+
subject.command_name.should == 'test_command'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "usage" do
|
16
|
+
context "without an argument" do
|
17
|
+
it "should return the set usage" do
|
18
|
+
subject.usage.should == '[options] PATH FILE [..]'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with an argument" do
|
23
|
+
let(:expected) { 'FOO' }
|
24
|
+
|
25
|
+
subject { Class.new(described_class) }
|
26
|
+
before { subject.usage expected }
|
27
|
+
|
28
|
+
it "should set the usage" do
|
29
|
+
subject.usage.should == expected
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "default" do
|
34
|
+
subject { Class.new(described_class).usage }
|
35
|
+
|
36
|
+
it { should == '[options]' }
|
37
|
+
end
|
38
|
+
|
39
|
+
context "inherited" do
|
40
|
+
let(:superclass) { TestCommand }
|
41
|
+
|
42
|
+
subject { Class.new(superclass).usage }
|
43
|
+
|
44
|
+
it "should default to the usage of the superclass" do
|
45
|
+
subject.should == superclass.usage
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "summary" do
|
51
|
+
context "without an argument" do
|
52
|
+
it "should return the set summary" do
|
53
|
+
subject.summary.should == 'Tests the default task'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with an argument" do
|
58
|
+
let(:expected) { 'Performs foo' }
|
59
|
+
|
60
|
+
subject { Class.new(described_class) }
|
61
|
+
before { subject.summary expected }
|
62
|
+
|
63
|
+
it "should set the usage" do
|
64
|
+
subject.summary.should == expected
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "default" do
|
69
|
+
subject { Class.new(described_class).summary }
|
70
|
+
|
71
|
+
it { should == nil }
|
72
|
+
end
|
73
|
+
|
74
|
+
context "inherited" do
|
75
|
+
let(:superclass) { TestCommand }
|
76
|
+
|
77
|
+
subject { Class.new(superclass).summary }
|
78
|
+
|
79
|
+
it "should default to the summary of the superclass" do
|
80
|
+
subject.should == superclass.summary
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "examples" do
|
86
|
+
context "without an argument" do
|
87
|
+
it "should return the set summary" do
|
88
|
+
# subject.example.should == 'Tests the default task'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "with an argument" do
|
93
|
+
let(:expected) do
|
94
|
+
['test_command --foo PATH', 'test_command --foo PATH FILE ...']
|
95
|
+
end
|
96
|
+
|
97
|
+
subject { Class.new(described_class) }
|
98
|
+
before { subject.examples expected }
|
99
|
+
|
100
|
+
it "should set the usage" do
|
101
|
+
subject.examples.should == expected
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "default" do
|
106
|
+
subject { Class.new(described_class).examples }
|
107
|
+
|
108
|
+
it { should == [] }
|
109
|
+
end
|
110
|
+
|
111
|
+
context "inherited" do
|
112
|
+
let(:superclass) { TestCommand }
|
113
|
+
|
114
|
+
subject { Class.new(superclass).examples }
|
115
|
+
|
116
|
+
it "should default to the examples of the superclass" do
|
117
|
+
subject.should == superclass.examples
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "options" do
|
123
|
+
subject { Class.new(described_class).options }
|
124
|
+
|
125
|
+
context "inherited" do
|
126
|
+
it "should be {} by default" do
|
127
|
+
subject.should == {}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context described_class do
|
132
|
+
subject { described_class.options }
|
133
|
+
|
134
|
+
it "should have a :verbose option" do
|
135
|
+
subject.should have_key(:verbose)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should have a :quiet option" do
|
139
|
+
subject.should have_key(:quiet)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should have a :silent option" do
|
143
|
+
subject.should have_key(:silent)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should have a :color option" do
|
147
|
+
subject.should have_key(:color)
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "color option" do
|
151
|
+
subject { described_class.new.color }
|
152
|
+
|
153
|
+
context "when $stdout is a TTY" do
|
154
|
+
it { should be_true }
|
155
|
+
end
|
156
|
+
|
157
|
+
context "when $stdout is not a TTY" do
|
158
|
+
before do
|
159
|
+
@old_stdout = $stdout
|
160
|
+
$stdout = StringIO.new
|
161
|
+
end
|
162
|
+
|
163
|
+
it { should be_false }
|
164
|
+
|
165
|
+
after do
|
166
|
+
$stdout = @old_stdout
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "option" do
|
174
|
+
let(:name) { :foo }
|
175
|
+
|
176
|
+
it "should define an option" do
|
177
|
+
subject.options[name].should be_kind_of(Hash)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should define a parameter" do
|
181
|
+
subject.should have_param(name)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "each_option" do
|
186
|
+
let(:expected) { [:verbose, :quiet, :silent, :color, :foo] }
|
187
|
+
|
188
|
+
it "should iterate over each option" do
|
189
|
+
names = []
|
190
|
+
|
191
|
+
subject.each_option do |name,options|
|
192
|
+
names << name
|
193
|
+
end
|
194
|
+
|
195
|
+
names.should =~ expected
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe "options?" do
|
200
|
+
it "should test if there are any defined options" do
|
201
|
+
subject.options?.should be_true
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "arguments" do
|
206
|
+
context "inherited" do
|
207
|
+
subject { Class.new(described_class).arguments }
|
208
|
+
|
209
|
+
it { should == [] }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe "argument" do
|
214
|
+
let(:name) { :foo }
|
215
|
+
|
216
|
+
subject { Class.new(described_class) }
|
217
|
+
before { subject.argument name }
|
218
|
+
|
219
|
+
it "should add to arguments" do
|
220
|
+
subject.arguments.should include(name)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should define a parameter" do
|
224
|
+
subject.should have_param(name)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "each_argument" do
|
229
|
+
let(:expected) { [:path, :files] }
|
230
|
+
|
231
|
+
it "should iterate over each option" do
|
232
|
+
names = []
|
233
|
+
|
234
|
+
subject.each_argument { |name| names << name }
|
235
|
+
|
236
|
+
names.should =~ expected
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "arguments?" do
|
241
|
+
it "should test if there are any defined arguments" do
|
242
|
+
subject.arguments?.should be_true
|
243
|
+
end
|
11
244
|
end
|
12
245
|
|
13
246
|
describe "#run" do
|
@@ -51,9 +284,4 @@ describe UI::CLI::Command do
|
|
51
284
|
subject.files.should == files
|
52
285
|
end
|
53
286
|
end
|
54
|
-
|
55
|
-
it "should have zero indentation by default" do
|
56
|
-
command = subject.new
|
57
|
-
command.instance_variable_get('@indent').should == 0
|
58
|
-
end
|
59
287
|
end
|