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.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.github/workflows/ruby.yml +41 -0
  4. data/.gitignore +12 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +160 -0
  7. data/.ruby-version +1 -0
  8. data/.yardopts +1 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +11 -0
  11. data/Gemfile +30 -0
  12. data/README.md +299 -0
  13. data/Rakefile +34 -0
  14. data/examples/ruby_shell.rb +11 -0
  15. data/gemspec.yml +28 -0
  16. data/lib/ronin/core/class_registry.rb +246 -0
  17. data/lib/ronin/core/cli/command.rb +87 -0
  18. data/lib/ronin/core/cli/command_shell/command.rb +110 -0
  19. data/lib/ronin/core/cli/command_shell.rb +345 -0
  20. data/lib/ronin/core/cli/generator/options/author.rb +106 -0
  21. data/lib/ronin/core/cli/generator/options/description.rb +54 -0
  22. data/lib/ronin/core/cli/generator/options/reference.rb +60 -0
  23. data/lib/ronin/core/cli/generator/options/summary.rb +54 -0
  24. data/lib/ronin/core/cli/generator.rb +238 -0
  25. data/lib/ronin/core/cli/logging.rb +59 -0
  26. data/lib/ronin/core/cli/options/param.rb +68 -0
  27. data/lib/ronin/core/cli/options/values/arches.rb +45 -0
  28. data/lib/ronin/core/cli/options/values/oses.rb +32 -0
  29. data/lib/ronin/core/cli/printing/arch.rb +71 -0
  30. data/lib/ronin/core/cli/printing/metadata.rb +113 -0
  31. data/lib/ronin/core/cli/printing/os.rb +54 -0
  32. data/lib/ronin/core/cli/printing/params.rb +69 -0
  33. data/lib/ronin/core/cli/ruby_shell.rb +131 -0
  34. data/lib/ronin/core/cli/shell.rb +186 -0
  35. data/lib/ronin/core/git.rb +73 -0
  36. data/lib/ronin/core/home.rb +86 -0
  37. data/lib/ronin/core/metadata/authors/author.rb +241 -0
  38. data/lib/ronin/core/metadata/authors.rb +120 -0
  39. data/lib/ronin/core/metadata/description.rb +100 -0
  40. data/lib/ronin/core/metadata/id.rb +88 -0
  41. data/lib/ronin/core/metadata/references.rb +87 -0
  42. data/lib/ronin/core/metadata/summary.rb +78 -0
  43. data/lib/ronin/core/metadata/version.rb +74 -0
  44. data/lib/ronin/core/params/exceptions.rb +38 -0
  45. data/lib/ronin/core/params/mixin.rb +317 -0
  46. data/lib/ronin/core/params/param.rb +137 -0
  47. data/lib/ronin/core/params/types/boolean.rb +64 -0
  48. data/lib/ronin/core/params/types/enum.rb +107 -0
  49. data/lib/ronin/core/params/types/float.rb +68 -0
  50. data/lib/ronin/core/params/types/integer.rb +100 -0
  51. data/lib/ronin/core/params/types/numeric.rb +106 -0
  52. data/lib/ronin/core/params/types/regexp.rb +67 -0
  53. data/lib/ronin/core/params/types/string.rb +118 -0
  54. data/lib/ronin/core/params/types/type.rb +54 -0
  55. data/lib/ronin/core/params/types/uri.rb +72 -0
  56. data/lib/ronin/core/params/types.rb +62 -0
  57. data/lib/ronin/core/params.rb +19 -0
  58. data/lib/ronin/core/version.rb +24 -0
  59. data/ronin-core.gemspec +59 -0
  60. data/spec/class_registry_spec.rb +224 -0
  61. data/spec/cli/command_shell/command_spec.rb +113 -0
  62. data/spec/cli/command_shell_spec.rb +1114 -0
  63. data/spec/cli/command_spec.rb +16 -0
  64. data/spec/cli/fixtures/irb_command +8 -0
  65. data/spec/cli/fixtures/template/dir/file1.txt +1 -0
  66. data/spec/cli/fixtures/template/dir/file2.txt +1 -0
  67. data/spec/cli/fixtures/template/file.erb +1 -0
  68. data/spec/cli/fixtures/template/file.txt +1 -0
  69. data/spec/cli/generator/options/author_spec.rb +121 -0
  70. data/spec/cli/generator/options/description_spec.rb +45 -0
  71. data/spec/cli/generator/options/reference_spec.rb +53 -0
  72. data/spec/cli/generator/options/summary_spec.rb +45 -0
  73. data/spec/cli/generator_spec.rb +244 -0
  74. data/spec/cli/logging_spec.rb +95 -0
  75. data/spec/cli/options/param_spec.rb +67 -0
  76. data/spec/cli/options/values/arches_spec.rb +62 -0
  77. data/spec/cli/printing/arch_spec.rb +130 -0
  78. data/spec/cli/printing/metadata_spec.rb +211 -0
  79. data/spec/cli/printing/os_spec.rb +64 -0
  80. data/spec/cli/printing/params_spec.rb +63 -0
  81. data/spec/cli/ruby_shell.rb +99 -0
  82. data/spec/cli/shell_spec.rb +211 -0
  83. data/spec/fixtures/example_class_registry/base_class.rb +9 -0
  84. data/spec/fixtures/example_class_registry/classes/loaded_class.rb +9 -0
  85. data/spec/fixtures/example_class_registry/classes/name_mismatch.rb +9 -0
  86. data/spec/fixtures/example_class_registry/classes/no_module.rb +4 -0
  87. data/spec/fixtures/example_class_registry.rb +8 -0
  88. data/spec/git_spec.rb +58 -0
  89. data/spec/home_spec.rb +64 -0
  90. data/spec/metadata/authors/author_spec.rb +335 -0
  91. data/spec/metadata/authors_spec.rb +126 -0
  92. data/spec/metadata/description_spec.rb +74 -0
  93. data/spec/metadata/id_spec.rb +92 -0
  94. data/spec/metadata/references_spec.rb +100 -0
  95. data/spec/metadata/summary_spec.rb +74 -0
  96. data/spec/metadata/version_spec.rb +72 -0
  97. data/spec/params/mixin_spec.rb +484 -0
  98. data/spec/params/param_spec.rb +164 -0
  99. data/spec/params/types/boolean_spec.rb +56 -0
  100. data/spec/params/types/enum_spec.rb +94 -0
  101. data/spec/params/types/float_spec.rb +107 -0
  102. data/spec/params/types/integer_spec.rb +155 -0
  103. data/spec/params/types/numeric_spec.rb +138 -0
  104. data/spec/params/types/regexp_spec.rb +64 -0
  105. data/spec/params/types/string_spec.rb +174 -0
  106. data/spec/params/types/type_spec.rb +14 -0
  107. data/spec/params/types/uri_spec.rb +62 -0
  108. data/spec/spec_helper.rb +11 -0
  109. 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