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,94 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/params/types/enum'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::Params::Types::Enum do
|
|
5
|
+
let(:values) { [:one, :two, :three] }
|
|
6
|
+
|
|
7
|
+
subject { described_class.new(values) }
|
|
8
|
+
|
|
9
|
+
describe "#initialize" do
|
|
10
|
+
it "must set #values" do
|
|
11
|
+
expect(subject.values).to eq(values)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "when given an empty Array" do
|
|
15
|
+
it do
|
|
16
|
+
expect {
|
|
17
|
+
described_class.new([])
|
|
18
|
+
}.to raise_error(ArgumentError,"cannot initialize an empty Enum")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe ".[]" do
|
|
24
|
+
subject { described_class[*values] }
|
|
25
|
+
|
|
26
|
+
it "must return a new #{described_class}" do
|
|
27
|
+
expect(subject).to be_kind_of(described_class)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "must set #values to the given arguments" do
|
|
31
|
+
expect(subject.values).to eq(values)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "when given no arguments" do
|
|
35
|
+
it do
|
|
36
|
+
expect {
|
|
37
|
+
described_class[]
|
|
38
|
+
}.to raise_error(ArgumentError,"cannot initialize an empty Enum")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "#coerce" do
|
|
44
|
+
context "when givne a Symbol" do
|
|
45
|
+
context "and when the Symbol is in #values" do
|
|
46
|
+
let(:value) { values[1] }
|
|
47
|
+
|
|
48
|
+
it "must return that Symbol" do
|
|
49
|
+
expect(subject.coerce(value)).to eq(value)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "but the Symbol is not within #values" do
|
|
54
|
+
let(:value) { :foo }
|
|
55
|
+
|
|
56
|
+
it do
|
|
57
|
+
expect {
|
|
58
|
+
subject.coerce(value)
|
|
59
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"unknown value (#{value.inspect})")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "when given a String" do
|
|
65
|
+
context "and it maps to one of the Symbols in #values" do
|
|
66
|
+
let(:value) { values[1].to_s }
|
|
67
|
+
|
|
68
|
+
it "must return the Symbol version of the String" do
|
|
69
|
+
expect(subject.coerce(value)).to eq(values[1])
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context "but it does not map to any of the Symbols in #values" do
|
|
74
|
+
let(:value) { "foo" }
|
|
75
|
+
|
|
76
|
+
it "must return the Symbol version of the String" do
|
|
77
|
+
expect {
|
|
78
|
+
subject.coerce(value)
|
|
79
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"unknown value (#{value.inspect})")
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context "when given a non-Symbol and non-String object" do
|
|
85
|
+
let(:value) { Object.new }
|
|
86
|
+
|
|
87
|
+
it do
|
|
88
|
+
expect {
|
|
89
|
+
subject.coerce(value)
|
|
90
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value must be either a Symbol or a String (#{value.inspect})")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/params/types/float'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::Params::Types::Float do
|
|
5
|
+
describe "#coerce" do
|
|
6
|
+
context "when given a Float" do
|
|
7
|
+
let(:value) { 0.5 }
|
|
8
|
+
|
|
9
|
+
it "must return the Float value" do
|
|
10
|
+
expect(subject.coerce(value)).to be(value)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "when given a String" do
|
|
15
|
+
context "and it is in the format of a decimal number" do
|
|
16
|
+
let(:value) { '0.5' }
|
|
17
|
+
|
|
18
|
+
it "must parse the String as a Float" do
|
|
19
|
+
expect(subject.coerce(value)).to eq(value.to_f)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "but it starts with a '+'" do
|
|
23
|
+
let(:value) { '+0.5' }
|
|
24
|
+
|
|
25
|
+
it "must parse the String as a Float" do
|
|
26
|
+
expect(subject.coerce(value)).to eq(value[1..].to_f)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "but it starts with a '-'" do
|
|
31
|
+
let(:value) { '-0.5' }
|
|
32
|
+
|
|
33
|
+
it "must parse the String as a negative Float" do
|
|
34
|
+
expect(subject.coerce(value)).to eq(-value[1..].to_f)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "and it is in the fomrat of a whole number" do
|
|
40
|
+
let(:value) { '1' }
|
|
41
|
+
|
|
42
|
+
it "must parse the String as a Float" do
|
|
43
|
+
expect(subject.coerce(value)).to eq(value.to_f)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "but it starts with a '+'" do
|
|
47
|
+
let(:value) { '+1' }
|
|
48
|
+
|
|
49
|
+
it "must parse the String as a Float" do
|
|
50
|
+
expect(subject.coerce(value)).to eq(value[1..].to_f)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "but it starts with a '-'" do
|
|
55
|
+
let(:value) { '-1' }
|
|
56
|
+
|
|
57
|
+
it "must parse the String as a negative Float" do
|
|
58
|
+
expect(subject.coerce(value)).to eq(-value[1..].to_f)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "but it contains non-numeric characters" do
|
|
64
|
+
let(:value) { "foo" }
|
|
65
|
+
|
|
66
|
+
it do
|
|
67
|
+
expect {
|
|
68
|
+
subject.coerce(value)
|
|
69
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value contains non-numeric characters (#{value.inspect})")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context "when given a non-Float and non-String object" do
|
|
75
|
+
context "and it defines a #to_f method" do
|
|
76
|
+
module TestTypesFloat
|
|
77
|
+
class ObjectWithToF
|
|
78
|
+
def to_f
|
|
79
|
+
0.5
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
let(:value) { TestTypesFloat::ObjectWithToF.new }
|
|
85
|
+
|
|
86
|
+
it "must call the #to_f method on the value" do
|
|
87
|
+
expect(subject.coerce(value)).to eq(value.to_f)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context "but it does not define a #to_f method" do
|
|
92
|
+
module TestTypesFloat
|
|
93
|
+
class ObjectWithoutToF
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
let(:value) { TestTypesFloat::ObjectWithoutToF.new }
|
|
98
|
+
|
|
99
|
+
it do
|
|
100
|
+
expect {
|
|
101
|
+
subject.coerce(value)
|
|
102
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value does not define a #to_f method (#{value.inspect})")
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/params/types/integer'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::Params::Types::Integer do
|
|
5
|
+
describe "#coerce" do
|
|
6
|
+
context "when given an Integer" do
|
|
7
|
+
let(:value) { 42 }
|
|
8
|
+
|
|
9
|
+
it "must return the Integer value" do
|
|
10
|
+
expect(subject.coerce(value)).to eq(value)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "when given a String" do
|
|
15
|
+
context "and the String contains decimal digits" do
|
|
16
|
+
let(:value) { "42" }
|
|
17
|
+
|
|
18
|
+
it "must parse the String as base 10 and return an Integer" do
|
|
19
|
+
expect(subject.coerce(value)).to eq(value.to_i)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "and the String also starts with a '+'" do
|
|
23
|
+
let(:value) { "+42" }
|
|
24
|
+
|
|
25
|
+
it "must parse the String as base 10 and return an Integer" do
|
|
26
|
+
expect(subject.coerce(value)).to eq(value.to_i)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "and the String also starts with a '-'" do
|
|
31
|
+
let(:value) { "-42" }
|
|
32
|
+
|
|
33
|
+
it "must parse the String as base 10 and return a negative Integer" do
|
|
34
|
+
expect(subject.coerce(value)).to eq(-value[1..].to_i)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "and the String contains hexadecimal digits" do
|
|
40
|
+
let(:value) { "ff" }
|
|
41
|
+
|
|
42
|
+
it "must parse the String as base 16 and return an Integer" do
|
|
43
|
+
expect(subject.coerce(value)).to eq(value.to_i(16))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context "and the String also starts with a '+'" do
|
|
47
|
+
let(:value) { "+ff" }
|
|
48
|
+
|
|
49
|
+
it "must parse the String as base 16 and return an Integer" do
|
|
50
|
+
expect(subject.coerce(value)).to eq(value.to_i(16))
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "and the String also starts with a '-'" do
|
|
55
|
+
let(:value) { "-ff" }
|
|
56
|
+
|
|
57
|
+
it "must parse the String as base 16 and return a negative Integer" do
|
|
58
|
+
expect(subject.coerce(value)).to eq(-value[1..].to_i(16))
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "but the String also starts with '0x'" do
|
|
63
|
+
let(:value) { "0xff" }
|
|
64
|
+
|
|
65
|
+
it "must remove the leading '0x' before parsing the String" do
|
|
66
|
+
expect(subject.coerce(value)).to eq(value[2..].to_i(16))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "and the String also starts with a '+'" do
|
|
70
|
+
let(:value) { "+0xff" }
|
|
71
|
+
|
|
72
|
+
it "must parse the String as base 16 and return a Integer" do
|
|
73
|
+
expect(subject.coerce(value)).to eq(value[3..].to_i(16))
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context "and the String also starts with a '-'" do
|
|
78
|
+
let(:value) { "-0xff" }
|
|
79
|
+
|
|
80
|
+
it "must parse the String as base 16 and return a negative Integer" do
|
|
81
|
+
expect(subject.coerce(value)).to eq(-value[3..].to_i(16))
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "and the String starts with '0b' and only contains chars 0 and 1" do
|
|
88
|
+
let(:value) { "0b111" }
|
|
89
|
+
|
|
90
|
+
it "must parse the String as binary and return an Integer" do
|
|
91
|
+
expect(subject.coerce(value)).to eq(value[2..].to_i(2))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context "and the String also starts with a '+'" do
|
|
95
|
+
let(:value) { "+0b111" }
|
|
96
|
+
|
|
97
|
+
it "must parse the String as base 16 and return a Integer" do
|
|
98
|
+
expect(subject.coerce(value)).to eq(value[3..].to_i(2))
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "and the String also starts with a '-'" do
|
|
103
|
+
let(:value) { "-0b111" }
|
|
104
|
+
|
|
105
|
+
it "must parse the String as base 16 and return a negative Integer" do
|
|
106
|
+
expect(subject.coerce(value)).to eq(-value[3..].to_i(2))
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context "but the String contains non-numeric characters" do
|
|
112
|
+
let(:value) { "bar" }
|
|
113
|
+
|
|
114
|
+
it do
|
|
115
|
+
expect {
|
|
116
|
+
subject.coerce(value)
|
|
117
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value contains non-numeric characters (#{value.inspect})")
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context "when given a non-Integer and non-String Object" do
|
|
123
|
+
context "and it defines a #to_i method" do
|
|
124
|
+
module TestTypesInteger
|
|
125
|
+
class ObjectWithToI
|
|
126
|
+
def to_i
|
|
127
|
+
42
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
let(:value) { TestTypesInteger::ObjectWithToI.new }
|
|
133
|
+
|
|
134
|
+
it "must call #to_i on the given value" do
|
|
135
|
+
expect(subject.coerce(value)).to eq(value.to_i)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
context "but it does not define a #to_i method" do
|
|
140
|
+
module TestTypesInteger
|
|
141
|
+
class ObjectWithoutToI
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
let(:value) { TestTypesInteger::ObjectWithoutToI.new }
|
|
146
|
+
|
|
147
|
+
it do
|
|
148
|
+
expect {
|
|
149
|
+
subject.coerce(value)
|
|
150
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value does not define a #to_i method (#{value.inspect})")
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/params/types/numeric'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::Params::Types::Numeric do
|
|
5
|
+
describe "#initialize" do
|
|
6
|
+
it "must default #min to nil" do
|
|
7
|
+
expect(subject.min).to be(nil)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "must default #max to nil" do
|
|
11
|
+
expect(subject.max).to be(nil)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "must default #range to nil" do
|
|
15
|
+
expect(subject.range).to be(nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context "when given the min: keyword argument" do
|
|
19
|
+
let(:min) { 42 }
|
|
20
|
+
|
|
21
|
+
subject { described_class.new(min: min) }
|
|
22
|
+
|
|
23
|
+
it "must set #min" do
|
|
24
|
+
expect(subject.min).to eq(min)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "when given the max: keyword argument" do
|
|
29
|
+
let(:max) { 42 }
|
|
30
|
+
|
|
31
|
+
subject { described_class.new(max: max) }
|
|
32
|
+
|
|
33
|
+
it "must set #max" do
|
|
34
|
+
expect(subject.max).to eq(max)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "when given the range: keyword argument" do
|
|
39
|
+
let(:range) { 1..42 }
|
|
40
|
+
|
|
41
|
+
subject { described_class.new(range: range) }
|
|
42
|
+
|
|
43
|
+
it "must set #range" do
|
|
44
|
+
expect(subject.range).to eq(range)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe "#coerce" do
|
|
50
|
+
context "when #range is set" do
|
|
51
|
+
let(:range) { 1..10 }
|
|
52
|
+
|
|
53
|
+
subject { described_class.new(range: range) }
|
|
54
|
+
|
|
55
|
+
context "and when the given number is within the range" do
|
|
56
|
+
let(:value) { 5 }
|
|
57
|
+
|
|
58
|
+
it "must return the number" do
|
|
59
|
+
expect(subject.coerce(value)).to eq(value)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "but the given number is not within the range" do
|
|
64
|
+
let(:value) { 20 }
|
|
65
|
+
|
|
66
|
+
it do
|
|
67
|
+
expect {
|
|
68
|
+
subject.coerce(value)
|
|
69
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value is not within the range of acceptable values #{range.begin}-#{range.end} (#{value.inspect})")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
context "when #min is set" do
|
|
75
|
+
let(:min) { 10 }
|
|
76
|
+
|
|
77
|
+
subject { described_class.new(min: min) }
|
|
78
|
+
|
|
79
|
+
context "and when then value is above the #min value" do
|
|
80
|
+
let(:value) { 20 }
|
|
81
|
+
|
|
82
|
+
it "must return the value" do
|
|
83
|
+
expect(subject.coerce(value)).to eq(value)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "and when then value is equal to the #min value" do
|
|
88
|
+
let(:value) { min }
|
|
89
|
+
|
|
90
|
+
it "must return the value" do
|
|
91
|
+
expect(subject.coerce(value)).to eq(value)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "but when the value is below the #min value" do
|
|
96
|
+
let(:value) { 5 }
|
|
97
|
+
|
|
98
|
+
it do
|
|
99
|
+
expect {
|
|
100
|
+
subject.coerce(value)
|
|
101
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value is below minimum value of #{min} (#{value.inspect})")
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
context "when #max is set" do
|
|
107
|
+
let(:max) { 10 }
|
|
108
|
+
|
|
109
|
+
subject { described_class.new(max: max) }
|
|
110
|
+
|
|
111
|
+
context "and when then value is below the #max value" do
|
|
112
|
+
let(:value) { 5 }
|
|
113
|
+
|
|
114
|
+
it "must return the value" do
|
|
115
|
+
expect(subject.coerce(value)).to eq(value)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context "and when then value is equal to the #max value" do
|
|
120
|
+
let(:value) { max }
|
|
121
|
+
|
|
122
|
+
it "must return the value" do
|
|
123
|
+
expect(subject.coerce(value)).to eq(value)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
context "but when the value is above the #max value" do
|
|
128
|
+
let(:value) { 20 }
|
|
129
|
+
|
|
130
|
+
it do
|
|
131
|
+
expect {
|
|
132
|
+
subject.coerce(value)
|
|
133
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value is above maximum value of #{max} (#{value.inspect})")
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/params/types/regexp'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::Params::Types::Regexp do
|
|
5
|
+
describe "#coerce" do
|
|
6
|
+
context "when given a Regexp value" do
|
|
7
|
+
let(:value) { /foo/ }
|
|
8
|
+
|
|
9
|
+
it "must return the Regexp" do
|
|
10
|
+
expect(subject.coerce(value)).to eq(value)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context "when given a String value" do
|
|
15
|
+
context "and the String is of the format '/.../'" do
|
|
16
|
+
let(:value) { "/foo/" }
|
|
17
|
+
|
|
18
|
+
it "must parse the contents of the String as a Regexp" do
|
|
19
|
+
expect(subject.coerce(value)).to eq(Regexp.new(value[1..-2]))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "but the String does not parse to a valid Regexp" do
|
|
24
|
+
let(:value) { "/foo[/" }
|
|
25
|
+
|
|
26
|
+
it do
|
|
27
|
+
expect {
|
|
28
|
+
subject.coerce(value)
|
|
29
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value is not a valid Regexp (#{value.inspect})")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "but the String does not start with a '/' character" do
|
|
34
|
+
let(:value) { "foo/" }
|
|
35
|
+
|
|
36
|
+
it do
|
|
37
|
+
expect {
|
|
38
|
+
subject.coerce(value)
|
|
39
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value must be of the format '/.../' (#{value.inspect})")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "but the String does not end with a '/' character" do
|
|
44
|
+
let(:value) { "/foo" }
|
|
45
|
+
|
|
46
|
+
it do
|
|
47
|
+
expect {
|
|
48
|
+
subject.coerce(value)
|
|
49
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value must be of the format '/.../' (#{value.inspect})")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "when given a non-Regexp and non-String value" do
|
|
55
|
+
let(:value) { Object.new }
|
|
56
|
+
|
|
57
|
+
it do
|
|
58
|
+
expect {
|
|
59
|
+
subject.coerce(value)
|
|
60
|
+
}.to raise_error(Ronin::Core::Params::ValidationError,"value must be either a String or a Regexp (#{value.inspect})")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|