ronin-core 0.1.0.beta1
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/.document +5 -0
- data/.github/workflows/ruby.yml +41 -0
- data/.gitignore +12 -0
- data/.rspec +1 -0
- data/.rubocop.yml +160 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +11 -0
- data/Gemfile +30 -0
- data/README.md +299 -0
- data/Rakefile +34 -0
- data/examples/ruby_shell.rb +11 -0
- data/gemspec.yml +28 -0
- data/lib/ronin/core/class_registry.rb +246 -0
- data/lib/ronin/core/cli/command.rb +87 -0
- data/lib/ronin/core/cli/command_shell/command.rb +110 -0
- data/lib/ronin/core/cli/command_shell.rb +345 -0
- data/lib/ronin/core/cli/generator/options/author.rb +106 -0
- data/lib/ronin/core/cli/generator/options/description.rb +54 -0
- data/lib/ronin/core/cli/generator/options/reference.rb +60 -0
- data/lib/ronin/core/cli/generator/options/summary.rb +54 -0
- data/lib/ronin/core/cli/generator.rb +238 -0
- data/lib/ronin/core/cli/logging.rb +59 -0
- data/lib/ronin/core/cli/options/param.rb +68 -0
- data/lib/ronin/core/cli/options/values/arches.rb +45 -0
- data/lib/ronin/core/cli/options/values/oses.rb +32 -0
- data/lib/ronin/core/cli/printing/arch.rb +71 -0
- data/lib/ronin/core/cli/printing/metadata.rb +113 -0
- data/lib/ronin/core/cli/printing/os.rb +54 -0
- data/lib/ronin/core/cli/printing/params.rb +69 -0
- data/lib/ronin/core/cli/ruby_shell.rb +131 -0
- data/lib/ronin/core/cli/shell.rb +186 -0
- data/lib/ronin/core/git.rb +73 -0
- data/lib/ronin/core/home.rb +86 -0
- data/lib/ronin/core/metadata/authors/author.rb +241 -0
- data/lib/ronin/core/metadata/authors.rb +120 -0
- data/lib/ronin/core/metadata/description.rb +100 -0
- data/lib/ronin/core/metadata/id.rb +88 -0
- data/lib/ronin/core/metadata/references.rb +87 -0
- data/lib/ronin/core/metadata/summary.rb +78 -0
- data/lib/ronin/core/metadata/version.rb +74 -0
- data/lib/ronin/core/params/exceptions.rb +38 -0
- data/lib/ronin/core/params/mixin.rb +317 -0
- data/lib/ronin/core/params/param.rb +137 -0
- data/lib/ronin/core/params/types/boolean.rb +64 -0
- data/lib/ronin/core/params/types/enum.rb +107 -0
- data/lib/ronin/core/params/types/float.rb +68 -0
- data/lib/ronin/core/params/types/integer.rb +100 -0
- data/lib/ronin/core/params/types/numeric.rb +106 -0
- data/lib/ronin/core/params/types/regexp.rb +67 -0
- data/lib/ronin/core/params/types/string.rb +118 -0
- data/lib/ronin/core/params/types/type.rb +54 -0
- data/lib/ronin/core/params/types/uri.rb +72 -0
- data/lib/ronin/core/params/types.rb +62 -0
- data/lib/ronin/core/params.rb +19 -0
- data/lib/ronin/core/version.rb +24 -0
- data/ronin-core.gemspec +59 -0
- data/spec/class_registry_spec.rb +224 -0
- data/spec/cli/command_shell/command_spec.rb +113 -0
- data/spec/cli/command_shell_spec.rb +1114 -0
- data/spec/cli/command_spec.rb +16 -0
- data/spec/cli/fixtures/irb_command +8 -0
- data/spec/cli/fixtures/template/dir/file1.txt +1 -0
- data/spec/cli/fixtures/template/dir/file2.txt +1 -0
- data/spec/cli/fixtures/template/file.erb +1 -0
- data/spec/cli/fixtures/template/file.txt +1 -0
- data/spec/cli/generator/options/author_spec.rb +121 -0
- data/spec/cli/generator/options/description_spec.rb +45 -0
- data/spec/cli/generator/options/reference_spec.rb +53 -0
- data/spec/cli/generator/options/summary_spec.rb +45 -0
- data/spec/cli/generator_spec.rb +244 -0
- data/spec/cli/logging_spec.rb +95 -0
- data/spec/cli/options/param_spec.rb +67 -0
- data/spec/cli/options/values/arches_spec.rb +62 -0
- data/spec/cli/printing/arch_spec.rb +130 -0
- data/spec/cli/printing/metadata_spec.rb +211 -0
- data/spec/cli/printing/os_spec.rb +64 -0
- data/spec/cli/printing/params_spec.rb +63 -0
- data/spec/cli/ruby_shell.rb +99 -0
- data/spec/cli/shell_spec.rb +211 -0
- data/spec/fixtures/example_class_registry/base_class.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/loaded_class.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/name_mismatch.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/no_module.rb +4 -0
- data/spec/fixtures/example_class_registry.rb +8 -0
- data/spec/git_spec.rb +58 -0
- data/spec/home_spec.rb +64 -0
- data/spec/metadata/authors/author_spec.rb +335 -0
- data/spec/metadata/authors_spec.rb +126 -0
- data/spec/metadata/description_spec.rb +74 -0
- data/spec/metadata/id_spec.rb +92 -0
- data/spec/metadata/references_spec.rb +100 -0
- data/spec/metadata/summary_spec.rb +74 -0
- data/spec/metadata/version_spec.rb +72 -0
- data/spec/params/mixin_spec.rb +484 -0
- data/spec/params/param_spec.rb +164 -0
- data/spec/params/types/boolean_spec.rb +56 -0
- data/spec/params/types/enum_spec.rb +94 -0
- data/spec/params/types/float_spec.rb +107 -0
- data/spec/params/types/integer_spec.rb +155 -0
- data/spec/params/types/numeric_spec.rb +138 -0
- data/spec/params/types/regexp_spec.rb +64 -0
- data/spec/params/types/string_spec.rb +174 -0
- data/spec/params/types/type_spec.rb +14 -0
- data/spec/params/types/uri_spec.rb +62 -0
- data/spec/spec_helper.rb +11 -0
- metadata +252 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/options/param'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
|
|
5
|
+
describe Ronin::Core::CLI::Options::Param do
|
|
6
|
+
module TestParamOption
|
|
7
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
8
|
+
include Ronin::Core::CLI::Options::Param
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:command_class) { TestParamOption::TestCommand }
|
|
13
|
+
|
|
14
|
+
describe ".included" do
|
|
15
|
+
subject { command_class }
|
|
16
|
+
|
|
17
|
+
it "must add a -p,--param option to the options" do
|
|
18
|
+
expect(subject.options[:param]).to_not be_nil
|
|
19
|
+
expect(subject.options[:param].value?).to be(true)
|
|
20
|
+
expect(subject.options[:param].value.type).to be_kind_of(Regexp)
|
|
21
|
+
expect(subject.options[:param].value.usage).to eq('NAME=VALUE')
|
|
22
|
+
expect(subject.options[:param].desc).to eq('Sets a param')
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
subject { command_class.new }
|
|
27
|
+
|
|
28
|
+
describe "#initialize" do
|
|
29
|
+
it "must set #params to an empty Hash" do
|
|
30
|
+
expect(subject.params).to eq({})
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "options" do
|
|
35
|
+
context "when given --param foo=bar" do
|
|
36
|
+
before { subject.option_parser.parse(%w[--param foo=bar]) }
|
|
37
|
+
|
|
38
|
+
it "must set the :foo key to 'bar' in #params" do
|
|
39
|
+
expect(subject.params[:foo]).to eq('bar')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "when given --param foo=" do
|
|
44
|
+
it do
|
|
45
|
+
expect {
|
|
46
|
+
subject.option_parser.parse(%w[--param foo=])
|
|
47
|
+
}.to raise_error(OptionParser::InvalidArgument)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "when given --param =bar" do
|
|
52
|
+
it do
|
|
53
|
+
expect {
|
|
54
|
+
subject.option_parser.parse(%w[--param =bar])
|
|
55
|
+
}.to raise_error(OptionParser::InvalidArgument)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context "when given --param =" do
|
|
60
|
+
it do
|
|
61
|
+
expect {
|
|
62
|
+
subject.option_parser.parse(%w[--param =])
|
|
63
|
+
}.to raise_error(OptionParser::InvalidArgument)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/options/values/arches'
|
|
3
|
+
|
|
4
|
+
describe "Ronin::Core::CLI::Options::Values::ARCHES" do
|
|
5
|
+
subject { Ronin::Core::CLI::Options::Values::ARCHES }
|
|
6
|
+
|
|
7
|
+
it "must map 'x86' to :x86" do
|
|
8
|
+
expect(subject['x86']).to eq(:x86)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "must map 'x86-64' to :x86_64" do
|
|
12
|
+
expect(subject['x86-64']).to eq(:x86_64)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "must map 'amd64' to :x86_64" do
|
|
16
|
+
expect(subject['amd64']).to eq(:x86_64)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "must map 'ia64' to :ia64" do
|
|
20
|
+
expect(subject['ia64']).to eq(:ia64)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "must map 'ppc' to :ppc" do
|
|
24
|
+
expect(subject['ppc']).to eq(:ppc)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "must map 'ppc64' to :ppc64" do
|
|
28
|
+
expect(subject['ppc64']).to eq(:ppc64)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "must map 'arm' to :arm" do
|
|
32
|
+
expect(subject['arm']).to eq(:arm)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "must map 'armbe' to :arm_be" do
|
|
36
|
+
expect(subject['armbe']).to eq(:arm_be)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "must map 'arm64' to :arm64" do
|
|
40
|
+
expect(subject['arm64']).to eq(:arm64)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "must map 'arm64be' to :arm64_be" do
|
|
44
|
+
expect(subject['arm64be']).to eq(:arm64_be)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "must map 'mips' to :mips" do
|
|
48
|
+
expect(subject['mips']).to eq(:mips)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "must map 'mipsle' to :mips_le" do
|
|
52
|
+
expect(subject['mipsle']).to eq(:mips_le)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "must map 'mips64' to :mips64" do
|
|
56
|
+
expect(subject['mips64']).to eq(:mips64)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "must map 'mips64le' to :mips64_le" do
|
|
60
|
+
expect(subject['mips64le']).to eq(:mips64_le)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/printing/arch'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
|
|
5
|
+
describe Ronin::Core::CLI::Printing::Arch do
|
|
6
|
+
module TestPrintingArch
|
|
7
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
8
|
+
include Ronin::Core::CLI::Printing::Arch
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:command_class) { TestPrintingArch::TestCommand }
|
|
13
|
+
subject { command_class.new }
|
|
14
|
+
|
|
15
|
+
describe "#arch_name" do
|
|
16
|
+
context "when given :x86" do
|
|
17
|
+
it "must return 'x86'" do
|
|
18
|
+
expect(subject.arch_name(:x86)).to eq('x86')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "when given :x86_64" do
|
|
23
|
+
it "must return 'x86-64'" do
|
|
24
|
+
expect(subject.arch_name(:x86_64)).to eq('x86-64')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "when given :ia64" do
|
|
29
|
+
it "must return 'ia64'" do
|
|
30
|
+
expect(subject.arch_name(:ia64)).to eq('IA64')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "when given :amd64" do
|
|
35
|
+
it "must return 'x86-64'" do
|
|
36
|
+
expect(subject.arch_name(:amd64)).to eq('x86-64')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "when given :ppc" do
|
|
41
|
+
it "must return 'PPC'" do
|
|
42
|
+
expect(subject.arch_name(:ppc)).to eq('PPC')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "when given :ppc64" do
|
|
47
|
+
it "must return 'PPC64'" do
|
|
48
|
+
expect(subject.arch_name(:ppc64)).to eq('PPC64')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "when given :mips" do
|
|
53
|
+
it "must return 'MIPS'" do
|
|
54
|
+
expect(subject.arch_name(:mips)).to eq('MIPS')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "when given :mips_le" do
|
|
59
|
+
it "must return 'MIPS (LE)'" do
|
|
60
|
+
expect(subject.arch_name(:mips_le)).to eq('MIPS (LE)')
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "when given :mips_be" do
|
|
65
|
+
it "must return 'MIPS'" do
|
|
66
|
+
expect(subject.arch_name(:mips_be)).to eq('MIPS')
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context "when given :mips64" do
|
|
71
|
+
it "must return 'MIPS64'" do
|
|
72
|
+
expect(subject.arch_name(:mips64)).to eq('MIPS64')
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "when given :mips64_le" do
|
|
77
|
+
it "must return 'MIPS64 (LE)'" do
|
|
78
|
+
expect(subject.arch_name(:mips64_le)).to eq('MIPS64 (LE)')
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "when given :mips64_be" do
|
|
83
|
+
it "must return 'MIPS64'" do
|
|
84
|
+
expect(subject.arch_name(:mips64_be)).to eq('MIPS64')
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context "when given :arm" do
|
|
89
|
+
it "must return 'ARM'" do
|
|
90
|
+
expect(subject.arch_name(:arm)).to eq('ARM')
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context "when given :arm_le" do
|
|
95
|
+
it "must return 'ARM'" do
|
|
96
|
+
expect(subject.arch_name(:arm_le)).to eq('ARM')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context "when given :arm_be" do
|
|
101
|
+
it "must return 'ARM (BE)'" do
|
|
102
|
+
expect(subject.arch_name(:arm_be)).to eq('ARM (BE)')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
context "when given :arm64" do
|
|
107
|
+
it "must return 'ARM64'" do
|
|
108
|
+
expect(subject.arch_name(:arm64)).to eq('ARM64')
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "when given :arm64_le" do
|
|
113
|
+
it "must return 'ARM64'" do
|
|
114
|
+
expect(subject.arch_name(:arm64_le)).to eq('ARM64')
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
context "when given :arm64_be" do
|
|
119
|
+
it "must return 'ARM64 (BE)'" do
|
|
120
|
+
expect(subject.arch_name(:arm64_be)).to eq('ARM64 (BE)')
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context "when given an unknown architecture" do
|
|
125
|
+
it "must return the String version of the architecture" do
|
|
126
|
+
expect(subject.arch_name(:foo)).to eq('foo')
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/printing/metadata'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
require 'ronin/core/metadata/authors'
|
|
5
|
+
require 'ronin/core/metadata/description'
|
|
6
|
+
require 'ronin/core/metadata/references'
|
|
7
|
+
|
|
8
|
+
describe Ronin::Core::CLI::Printing::Metadata do
|
|
9
|
+
module TestPrintingMetadata
|
|
10
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
11
|
+
include Ronin::Core::CLI::Printing::Metadata
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:command_class) { TestPrintingMetadata::TestCommand }
|
|
16
|
+
subject { command_class.new }
|
|
17
|
+
|
|
18
|
+
describe ".included" do
|
|
19
|
+
subject { command_class }
|
|
20
|
+
|
|
21
|
+
it "must add a -v,--verbose option" do
|
|
22
|
+
expect(subject.options[:verbose]).to_not be_nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "#print_authors" do
|
|
27
|
+
module TestPrintingAuthors
|
|
28
|
+
class WithoutAuthors
|
|
29
|
+
include Ronin::Core::Metadata::Authors
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class WithAuthors
|
|
33
|
+
include Ronin::Core::Metadata::Authors
|
|
34
|
+
|
|
35
|
+
author 'John Doe', email: 'john.doe@example.com',
|
|
36
|
+
pgp: '0x123456789',
|
|
37
|
+
website: 'https://johndoe.name',
|
|
38
|
+
blog: 'https://johndoe.name/blog',
|
|
39
|
+
github: '@johndoe',
|
|
40
|
+
gitlab: '@johndoe',
|
|
41
|
+
twitter: '@johndoe',
|
|
42
|
+
discord: 'https://discord.gg/1234'
|
|
43
|
+
|
|
44
|
+
author 'John Smith', email: 'john.smith@example.com',
|
|
45
|
+
pgp: '0xABCDEF',
|
|
46
|
+
website: 'https://johnsmith.name',
|
|
47
|
+
blog: 'https://johnsmith.name/blog',
|
|
48
|
+
github: '@john.smith',
|
|
49
|
+
gitlab: '@john.smith',
|
|
50
|
+
twitter: '@john.smith',
|
|
51
|
+
discord: 'https://discord.gg/ABCDEF'
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "when the class does not have any authors" do
|
|
56
|
+
let(:klass) { TestPrintingAuthors::WithoutAuthors }
|
|
57
|
+
|
|
58
|
+
it "must not print anything" do
|
|
59
|
+
expect {
|
|
60
|
+
subject.print_authors(klass)
|
|
61
|
+
}.to_not output.to_stdout
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "when the class does have authors" do
|
|
66
|
+
let(:klass) { TestPrintingAuthors::WithAuthors }
|
|
67
|
+
|
|
68
|
+
it "must print 'Authors:' and a list of authors" do
|
|
69
|
+
expect {
|
|
70
|
+
subject.print_authors(klass)
|
|
71
|
+
}.to output(
|
|
72
|
+
[
|
|
73
|
+
'Authors:',
|
|
74
|
+
'',
|
|
75
|
+
" * #{klass.authors[0]}",
|
|
76
|
+
" * #{klass.authors[1]}",
|
|
77
|
+
'',
|
|
78
|
+
''
|
|
79
|
+
].join($/)
|
|
80
|
+
).to_stdout
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "when --verbose mode is enabled" do
|
|
84
|
+
before { allow(subject).to receive(:verbose?).and_return(true) }
|
|
85
|
+
|
|
86
|
+
it "must print the authors and any author metadata as indented lists" do
|
|
87
|
+
expect {
|
|
88
|
+
subject.print_authors(klass)
|
|
89
|
+
}.to output(
|
|
90
|
+
[
|
|
91
|
+
'Authors:',
|
|
92
|
+
'',
|
|
93
|
+
" * #{klass.authors[0]}",
|
|
94
|
+
" * PGP: #{klass.authors[0].pgp}",
|
|
95
|
+
" * Website: #{klass.authors[0].website}",
|
|
96
|
+
" * Blog: #{klass.authors[0].blog}",
|
|
97
|
+
" * GitHub: #{klass.authors[0].github_url}",
|
|
98
|
+
" * GitLab: #{klass.authors[0].gitlab_url}",
|
|
99
|
+
" * Twitter: #{klass.authors[0].twitter_url}",
|
|
100
|
+
" * Discord: #{klass.authors[0].discord}",
|
|
101
|
+
" * #{klass.authors[1]}",
|
|
102
|
+
" * PGP: #{klass.authors[1].pgp}",
|
|
103
|
+
" * Website: #{klass.authors[1].website}",
|
|
104
|
+
" * Blog: #{klass.authors[1].blog}",
|
|
105
|
+
" * GitHub: #{klass.authors[1].github_url}",
|
|
106
|
+
" * GitLab: #{klass.authors[1].gitlab_url}",
|
|
107
|
+
" * Twitter: #{klass.authors[1].twitter_url}",
|
|
108
|
+
" * Discord: #{klass.authors[1].discord}",
|
|
109
|
+
'',
|
|
110
|
+
''
|
|
111
|
+
].join($/)
|
|
112
|
+
).to_stdout
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe "#print_description" do
|
|
119
|
+
module TestPrintingDescription
|
|
120
|
+
class WithoutDescription
|
|
121
|
+
include Ronin::Core::Metadata::Description
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
class WithDescription
|
|
125
|
+
include Ronin::Core::Metadata::Description
|
|
126
|
+
|
|
127
|
+
description <<~DESC
|
|
128
|
+
Foo bar baz
|
|
129
|
+
|
|
130
|
+
Qux quux gorge
|
|
131
|
+
DESC
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context "when the class does not have a description" do
|
|
136
|
+
let(:klass) { TestPrintingDescription::WithoutDescription }
|
|
137
|
+
|
|
138
|
+
it "must not print anything" do
|
|
139
|
+
expect {
|
|
140
|
+
subject.print_description(klass)
|
|
141
|
+
}.to_not output.to_stdout
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context "when the class does have a description" do
|
|
146
|
+
let(:klass) { TestPrintingDescription::WithDescription }
|
|
147
|
+
|
|
148
|
+
it "must print 'Description:' and the indented description text" do
|
|
149
|
+
expect {
|
|
150
|
+
subject.print_description(klass)
|
|
151
|
+
}.to output(
|
|
152
|
+
[
|
|
153
|
+
'Description:',
|
|
154
|
+
'',
|
|
155
|
+
" #{klass.description.lines[0].chomp}",
|
|
156
|
+
" #{klass.description.lines[1].chomp}",
|
|
157
|
+
" #{klass.description.lines[2].chomp}",
|
|
158
|
+
'',
|
|
159
|
+
''
|
|
160
|
+
].join($/)
|
|
161
|
+
).to_stdout
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe "#print_references" do
|
|
167
|
+
module TestPrintingReferences
|
|
168
|
+
class WithoutReferences
|
|
169
|
+
include Ronin::Core::Metadata::References
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
class WithReferences
|
|
173
|
+
include Ronin::Core::Metadata::References
|
|
174
|
+
|
|
175
|
+
references [
|
|
176
|
+
'https://example.com/url1',
|
|
177
|
+
'https://example.com/url2'
|
|
178
|
+
]
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
context "when the class has no references" do
|
|
183
|
+
let(:klass) { TestPrintingReferences::WithoutReferences }
|
|
184
|
+
|
|
185
|
+
it "must not print anything" do
|
|
186
|
+
expect {
|
|
187
|
+
subject.print_references(klass)
|
|
188
|
+
}.to_not output.to_stdout
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
context "when the class has references" do
|
|
193
|
+
let(:klass) { TestPrintingReferences::WithReferences }
|
|
194
|
+
|
|
195
|
+
it "must print 'References:' and the list of reference URLs" do
|
|
196
|
+
expect {
|
|
197
|
+
subject.print_references(klass)
|
|
198
|
+
}.to output(
|
|
199
|
+
[
|
|
200
|
+
'References:',
|
|
201
|
+
'',
|
|
202
|
+
" * #{klass.references[0]}",
|
|
203
|
+
" * #{klass.references[1]}",
|
|
204
|
+
'',
|
|
205
|
+
''
|
|
206
|
+
].join($/)
|
|
207
|
+
).to_stdout
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/printing/os'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
|
|
5
|
+
describe Ronin::Core::CLI::Printing::OS do
|
|
6
|
+
module TestPrintingOS
|
|
7
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
8
|
+
include Ronin::Core::CLI::Printing::OS
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:command_class) { TestPrintingOS::TestCommand }
|
|
13
|
+
subject { command_class.new }
|
|
14
|
+
|
|
15
|
+
describe "#os_name" do
|
|
16
|
+
context "when given :unix" do
|
|
17
|
+
it "must return 'UNIX'" do
|
|
18
|
+
expect(subject.os_name(:unix)).to eq('UNIX')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "when given :bsd" do
|
|
23
|
+
it "must return 'BSD'" do
|
|
24
|
+
expect(subject.os_name(:bsd)).to eq('BSD')
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "when given :freebsd" do
|
|
29
|
+
it "must return 'FreeBSD'" do
|
|
30
|
+
expect(subject.os_name(:freebsd)).to eq('FreeBSD')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "when given :openbsd" do
|
|
35
|
+
it "must return 'OpenBSD'" do
|
|
36
|
+
expect(subject.os_name(:openbsd)).to eq('OpenBSD')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "when given :netbsd" do
|
|
41
|
+
it "must return 'NetBSD'" do
|
|
42
|
+
expect(subject.os_name(:netbsd)).to eq('NetBSD')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "when given :linux" do
|
|
47
|
+
it "must return 'Linux'" do
|
|
48
|
+
expect(subject.os_name(:linux)).to eq('Linux')
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "when given :macos" do
|
|
53
|
+
it "must return 'macOS'" do
|
|
54
|
+
expect(subject.os_name(:macos)).to eq('macOS')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "when given :windows" do
|
|
59
|
+
it "must return 'Windows'" do
|
|
60
|
+
expect(subject.os_name(:windows)).to eq('Windows')
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/printing/params'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
require 'ronin/core/params/mixin'
|
|
5
|
+
|
|
6
|
+
describe Ronin::Core::CLI::Printing::Params do
|
|
7
|
+
module TestPrintingParams
|
|
8
|
+
class TestClass
|
|
9
|
+
|
|
10
|
+
include Ronin::Core::Params::Mixin
|
|
11
|
+
|
|
12
|
+
param :foo, String, required: true,
|
|
13
|
+
desc: 'Foo param'
|
|
14
|
+
param :bar, Integer, default: 42,
|
|
15
|
+
desc: 'Bar param'
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class TestClassWithoutParams
|
|
20
|
+
include Ronin::Core::Params::Mixin
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
24
|
+
include Ronin::Core::CLI::Printing::Params
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
let(:test_class) { TestPrintingParams::TestClass }
|
|
29
|
+
let(:test_command) { TestPrintingParams::TestCommand }
|
|
30
|
+
subject { test_command.new }
|
|
31
|
+
|
|
32
|
+
describe "#print_params" do
|
|
33
|
+
context "when the class has defined params" do
|
|
34
|
+
it "must print Params: and the params table" do
|
|
35
|
+
expect {
|
|
36
|
+
subject.print_params(test_class)
|
|
37
|
+
}.to output(
|
|
38
|
+
[
|
|
39
|
+
"Params:",
|
|
40
|
+
"",
|
|
41
|
+
" ┌──────┬─────────┬──────────┬─────────┬─────────────┐",
|
|
42
|
+
" │ Name │ Type │ Required │ Default │ Description │",
|
|
43
|
+
" ├──────┼─────────┼──────────┼─────────┼─────────────┤",
|
|
44
|
+
" │ foo │ String │ Yes │ │ Foo param │",
|
|
45
|
+
" │ bar │ Integer │ No │ 42 │ Bar param │",
|
|
46
|
+
" └──────┴─────────┴──────────┴─────────┴─────────────┘",
|
|
47
|
+
""
|
|
48
|
+
].join($/)
|
|
49
|
+
).to_stdout
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "when the class does not have any defined params" do
|
|
54
|
+
let(:test_class) { TestPrintingParams::TestClassWithoutParams }
|
|
55
|
+
|
|
56
|
+
it "must not print anything" do
|
|
57
|
+
expect {
|
|
58
|
+
subject.print_params(test_class)
|
|
59
|
+
}.to_not output.to_stdout
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/ruby_shell'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::CLI::RubyShell do
|
|
5
|
+
describe "#initialize" do
|
|
6
|
+
it "must default #name to 'ronin'" do
|
|
7
|
+
expect(subject.name).to eq('ronin')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context "when given a name: keyword argument" do
|
|
11
|
+
let(:name) { 'ronin-foo' }
|
|
12
|
+
|
|
13
|
+
subject { described_class.new(name: name) }
|
|
14
|
+
|
|
15
|
+
it "must set #name" do
|
|
16
|
+
expect(subject.name).to eq(name)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "must default #context to nil" do
|
|
21
|
+
expect(subject.context).to be(nil)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "when given a context: keyword argument" do
|
|
25
|
+
let(:context) { Object.new }
|
|
26
|
+
|
|
27
|
+
subject { described_class.new(context: context) }
|
|
28
|
+
|
|
29
|
+
it "must set #context" do
|
|
30
|
+
expect(subject.context).to be(context)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "#configure" do
|
|
36
|
+
before { subject.configure }
|
|
37
|
+
|
|
38
|
+
it "must call IRB.setup" do
|
|
39
|
+
expect(IRB.conf.length).to be > 1
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "must set IRB.conf[:IRB_NAME] to #name" do
|
|
43
|
+
expect(IRB.conf[:IRB_NAME]).to eq(subject.name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
let(:colors) { subject.colors(STDOUT) }
|
|
47
|
+
let(:red) { colors::RED }
|
|
48
|
+
let(:bright_red) { colors::BRIGHT_RED }
|
|
49
|
+
let(:bold) { colors::BOLD }
|
|
50
|
+
let(:reset_intensity) { colors::RESET_INTENSITY }
|
|
51
|
+
let(:reset_color) { colors::RESET_COLOR }
|
|
52
|
+
|
|
53
|
+
it "must set IRB.conf[:PROMPT][:RONIN]" do
|
|
54
|
+
expect(IRB.conf[:PROMPT][:RONIN]).to eq(
|
|
55
|
+
{
|
|
56
|
+
AUTO_INDENT: true,
|
|
57
|
+
PROMPT_I: "#{red}irb#{reset_color}#{bold}#{bright_red}(#{reset_color}#{reset_intensity}#{red}%N#{reset_color}#{bold}#{bright_red})#{reset_color}#{reset_intensity}#{bold}#{bright_red}>#{reset_color}#{reset_intensity} ",
|
|
58
|
+
PROMPT_S: "#{red}irb#{reset_color}#{bold}#{bright_red}(#{reset_color}#{reset_intensity}#{red}%N#{reset_color}#{bold}#{bright_red})#{reset_color}#{reset_intensity}%l ",
|
|
59
|
+
PROMPT_C: "#{red}irb#{reset_color}#{bold}#{bright_red}(#{reset_color}#{reset_intensity}#{red}%N#{reset_color}#{bold}#{bright_red})#{reset_color}#{reset_intensity}* ",
|
|
60
|
+
RETURN: "=> %s#{$/}"
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "must set IRB.conf[:PROMPT_MODE] to :RONIN" do
|
|
66
|
+
expect(IRB.conf[:PROMPT_MODE]).to eq(:RONIN)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
after do
|
|
70
|
+
IRB.conf[:IRB_NAME] = nil
|
|
71
|
+
IRB.conf[:PROMPT].delete(:RONIN)
|
|
72
|
+
IRB.conf[:PROMPT_MODE] = :DEFAULT
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe "#start" do
|
|
77
|
+
let(:fixtures_dir) { File.expand_path(File.join(__dir__,'fixtures')) }
|
|
78
|
+
let(:console_bin) { File.join(fixtures_dir,'irb_command') }
|
|
79
|
+
|
|
80
|
+
it "must print a prompt then read and evaluate Ruby" do
|
|
81
|
+
output = nil
|
|
82
|
+
|
|
83
|
+
IO.popen(console_bin,'r+') do |io|
|
|
84
|
+
io.puts "1 + 1"
|
|
85
|
+
io.puts "exit"
|
|
86
|
+
|
|
87
|
+
output = io.read
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
expect(output).to eq([
|
|
91
|
+
"Switch to inspect mode.",
|
|
92
|
+
"irb(ronin)> 1 + 1",
|
|
93
|
+
"=> 2",
|
|
94
|
+
"irb(ronin)> exit",
|
|
95
|
+
''
|
|
96
|
+
].join($/))
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|