json_schemer-fuzz 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +2 -0
- data/CHANGELOG.md +19 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/CONTRIBUTING.md +47 -0
- data/LICENSE.txt +22 -0
- data/README.md +221 -0
- data/SECURITY.md +13 -0
- data/lib/json_schemer/fuzz/keyword/additional_properties.rb +60 -0
- data/lib/json_schemer/fuzz/keyword/all_of.rb +46 -0
- data/lib/json_schemer/fuzz/keyword/any_of.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/dependencies.rb +49 -0
- data/lib/json_schemer/fuzz/keyword/enum.rb +32 -0
- data/lib/json_schemer/fuzz/keyword/format.rb +119 -0
- data/lib/json_schemer/fuzz/keyword/items.rb +67 -0
- data/lib/json_schemer/fuzz/keyword/max_items.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/max_length.rb +28 -0
- data/lib/json_schemer/fuzz/keyword/max_properties.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/maximum.rb +44 -0
- data/lib/json_schemer/fuzz/keyword/min_items.rb +42 -0
- data/lib/json_schemer/fuzz/keyword/min_length.rb +27 -0
- data/lib/json_schemer/fuzz/keyword/min_properties.rb +37 -0
- data/lib/json_schemer/fuzz/keyword/minimum.rb +43 -0
- data/lib/json_schemer/fuzz/keyword/multiple_of.rb +27 -0
- data/lib/json_schemer/fuzz/keyword/not.rb +26 -0
- data/lib/json_schemer/fuzz/keyword/one_of.rb +74 -0
- data/lib/json_schemer/fuzz/keyword/pattern.rb +17 -0
- data/lib/json_schemer/fuzz/keyword/properties.rb +38 -0
- data/lib/json_schemer/fuzz/keyword/required.rb +39 -0
- data/lib/json_schemer/fuzz/keyword/unique_items.rb +31 -0
- data/lib/json_schemer/fuzz/keyword.rb +29 -0
- data/lib/json_schemer/fuzz/primitive_type/array.rb +50 -0
- data/lib/json_schemer/fuzz/primitive_type/boolean.rb +29 -0
- data/lib/json_schemer/fuzz/primitive_type/integer.rb +55 -0
- data/lib/json_schemer/fuzz/primitive_type/null.rb +30 -0
- data/lib/json_schemer/fuzz/primitive_type/number.rb +50 -0
- data/lib/json_schemer/fuzz/primitive_type/object.rb +54 -0
- data/lib/json_schemer/fuzz/primitive_type/string.rb +50 -0
- data/lib/json_schemer/fuzz/primitive_type.rb +31 -0
- data/lib/json_schemer/fuzz/version.rb +7 -0
- data/lib/json_schemer/fuzz.rb +170 -0
- data/lib/json_schemer-fuzz.rb +7 -0
- data.tar.gz.sig +0 -0
- metadata +387 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,119 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Format
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
format = attributes["format"]
|
9
|
+
raise "No format keyword given: #{attributes}" unless format
|
10
|
+
|
11
|
+
if invalid_params = format_to_invalid_params(format)
|
12
|
+
invalid_params
|
13
|
+
else
|
14
|
+
raise "invalid format type: #{attributes}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_param(attributes)
|
19
|
+
format = attributes["format"]
|
20
|
+
raise "No format keyword given: #{attributes}" unless format
|
21
|
+
|
22
|
+
if valid_params = format_to_valid_params(format)
|
23
|
+
valid_params.sample
|
24
|
+
else
|
25
|
+
raise "invalid format type: #{attributes}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def format_to_invalid_params(format)
|
32
|
+
{
|
33
|
+
"ipv4" => [
|
34
|
+
"1",
|
35
|
+
"1.1",
|
36
|
+
"1.1.1",
|
37
|
+
"1.1.1.1.1.1.1.1.1.1.1.1.1",
|
38
|
+
"1.1.1.300",
|
39
|
+
"1.1.1.1b",
|
40
|
+
"b1.1.1.1",
|
41
|
+
"donut",
|
42
|
+
],
|
43
|
+
"ipv6" => [
|
44
|
+
"1111:2222:8888:99999:aaaa:cccc:eeee:ffff",
|
45
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:gggg",
|
46
|
+
"1111:2222::9999::cccc:eeee:ffff",
|
47
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:ffff:bbbb",
|
48
|
+
],
|
49
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
50
|
+
"time" => [
|
51
|
+
"12:00",
|
52
|
+
"12:00:60",
|
53
|
+
"12:60:00",
|
54
|
+
"24:00:00",
|
55
|
+
"0:00:00",
|
56
|
+
"-12:00:00",
|
57
|
+
"12:00:00b",
|
58
|
+
"12:00:00",
|
59
|
+
],
|
60
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
61
|
+
"date" => [
|
62
|
+
"2010-01-32",
|
63
|
+
"n2010-01-01",
|
64
|
+
"2010-1-01",
|
65
|
+
"2010-01-1",
|
66
|
+
"2010-01-01n",
|
67
|
+
],
|
68
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
69
|
+
"date-time" => [
|
70
|
+
"2010-01-32T12:00:00Z",
|
71
|
+
"2010-13-01T12:00:00Z",
|
72
|
+
"2010-01-01T24:00:00Z",
|
73
|
+
"2010-01-01T12:60:00Z",
|
74
|
+
"2010-01-01T12:00:60Z",
|
75
|
+
"2010-01-0112:00:00Z",
|
76
|
+
"2010-01-01T12:00:00+0000",
|
77
|
+
],
|
78
|
+
"uri" => [
|
79
|
+
"::hoge",
|
80
|
+
],
|
81
|
+
"email" => [
|
82
|
+
"@example.com",
|
83
|
+
"hoge",
|
84
|
+
"http://example.com",
|
85
|
+
],
|
86
|
+
}[format]
|
87
|
+
end
|
88
|
+
|
89
|
+
def format_to_valid_params(format)
|
90
|
+
{
|
91
|
+
"ipv4" => ["1.1.1.1"],
|
92
|
+
"ipv6" => [
|
93
|
+
"1111:2222:8888:9999:aaaa:cccc:eeee:ffff",
|
94
|
+
"1111:0:8888:0:0:0:eeee:ffff",
|
95
|
+
"1111:2222:8888::eeee:ffff",
|
96
|
+
],
|
97
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
98
|
+
"time" => ["12:00:00Z"],
|
99
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
100
|
+
"date" => ["1992-06-27"],
|
101
|
+
# https://ijmacd.github.io/rfc3339-iso8601/
|
102
|
+
"date-time" => [
|
103
|
+
"2010-01-01T12:00:00Z",
|
104
|
+
"2010-01-01T12:00:00.1Z",
|
105
|
+
# TODO: Uncomment once fixed in json_schemer: https://github.com/davishmcclurg/json_schemer/issues/151
|
106
|
+
# Valid ISO-8601, but not valid RFC-3339
|
107
|
+
# "2010-01-01T12:00:00,1Z",
|
108
|
+
"2010-01-01T12:00:00z", # RFC-3339 is case-insensitive!
|
109
|
+
"2010-01-01T12:00:00+00:00",
|
110
|
+
],
|
111
|
+
"uri" => ["http://example.com"],
|
112
|
+
"email" => ["hoge@example.com"],
|
113
|
+
}[format]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Items
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
9
|
+
items = attributes.delete("items")
|
10
|
+
raise "No items keyword given: #{attributes}" unless items
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
|
14
|
+
if items.instance_of?(Hash)
|
15
|
+
invalid_param = []
|
16
|
+
JSONSchemer::Fuzz.generate(items).each do |invalid_item|
|
17
|
+
invalid_param << invalid_item
|
18
|
+
end
|
19
|
+
generated_params << invalid_param
|
20
|
+
else
|
21
|
+
invalid_param = []
|
22
|
+
items.each do |item|
|
23
|
+
JSONSchemer::Fuzz.generate(item).each do |invalid_item|
|
24
|
+
invalid_param << invalid_item
|
25
|
+
end
|
26
|
+
end
|
27
|
+
generated_params << invalid_param
|
28
|
+
end
|
29
|
+
|
30
|
+
if attributes.key?("additionalItems")
|
31
|
+
additional_items = attributes.delete("additionalItems")
|
32
|
+
template = valid_param(attributes.merge("items" => items))
|
33
|
+
|
34
|
+
if additional_items
|
35
|
+
template << JSONSchemer::Fuzz.generate(additional_items).sample
|
36
|
+
generated_params << template
|
37
|
+
else
|
38
|
+
template << template.sample
|
39
|
+
generated_params << template
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
generated_params
|
44
|
+
end
|
45
|
+
|
46
|
+
def valid_param(attributes)
|
47
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
48
|
+
items = attributes.delete("items")
|
49
|
+
raise "No items keyword given: #{attributes}" unless items
|
50
|
+
|
51
|
+
generated_param = []
|
52
|
+
|
53
|
+
if items.instance_of?(Hash)
|
54
|
+
generated_param << JSONSchemer::Fuzz.default_param(items)
|
55
|
+
else
|
56
|
+
items.each do |item|
|
57
|
+
generated_param << JSONSchemer::Fuzz.default_param(item)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
generated_param
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MaxItems
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
9
|
+
max_items = attributes.delete("maxItems")
|
10
|
+
raise "No maxItems keyword given: #{attributes}" unless max_items
|
11
|
+
|
12
|
+
generated_params = []
|
13
|
+
invalid_param = []
|
14
|
+
|
15
|
+
(max_items + 1).times do
|
16
|
+
item = JSONSchemer::Fuzz.default_param(attributes)
|
17
|
+
item = "null" if item.nil?
|
18
|
+
invalid_param << item
|
19
|
+
end
|
20
|
+
|
21
|
+
generated_params << invalid_param
|
22
|
+
|
23
|
+
generated_params
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_param(attributes)
|
27
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
28
|
+
max_items = attributes.delete("maxItems")
|
29
|
+
raise "No maxItems keyword given: #{attributes}" unless max_items
|
30
|
+
|
31
|
+
generated_param = []
|
32
|
+
|
33
|
+
max_items.times do
|
34
|
+
generated_param << JSONSchemer::Fuzz.default_param(attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
generated_param
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MaxLength
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
max_length = attributes["maxLength"]
|
9
|
+
raise "No maxLength keyword given: #{attributes}" unless max_length
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
generated_params << /\w{1}/.gen * (max_length + 1)
|
14
|
+
|
15
|
+
generated_params
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_param(attributes)
|
19
|
+
max_length = attributes["maxLength"]
|
20
|
+
raise "No maxLength keyword given: #{attributes}" unless max_length
|
21
|
+
|
22
|
+
/\w{1}/.gen * max_length
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MaxProperties
|
5
|
+
class << self
|
6
|
+
# @return Array
|
7
|
+
def invalid_params(attributes)
|
8
|
+
max_properties = attributes["maxProperties"]
|
9
|
+
raise "No maxProperties keyword given: #{attributes}" unless max_properties
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
invalid_param = {}
|
13
|
+
|
14
|
+
template = valid_param(attributes)
|
15
|
+
|
16
|
+
while template.size <= max_properties
|
17
|
+
key = /\w+/.gen
|
18
|
+
template[key] = template[template.keys.sample]
|
19
|
+
end
|
20
|
+
|
21
|
+
[template]
|
22
|
+
end
|
23
|
+
|
24
|
+
def valid_param(attributes)
|
25
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
26
|
+
max_properties = attributes.delete("maxProperties")
|
27
|
+
raise "No maxProperties keyword given: #{attributes}" unless max_properties
|
28
|
+
|
29
|
+
template = JSONSchemer::Fuzz.default_param(attributes)
|
30
|
+
|
31
|
+
while template.size > max_properties
|
32
|
+
requred_keys = attributes["required"] || []
|
33
|
+
key = (template.keys - requred_keys).sample
|
34
|
+
template.delete(template.keys.sample)
|
35
|
+
end
|
36
|
+
|
37
|
+
template
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Maximum
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
maximum_value = attributes["maximum"]
|
8
|
+
raise "No maximum keyword given: #{attributes}" unless maximum_value
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
12
|
+
|
13
|
+
if attributes["exclusiveMaximum"]
|
14
|
+
generated_params.push(maximum_value)
|
15
|
+
else
|
16
|
+
generated_params.push(maximum_value + unit_value)
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
maximum_value = attributes["maximum"]
|
24
|
+
raise "No maximum keyword given: #{attributes}" unless maximum_value
|
25
|
+
|
26
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
27
|
+
maximum_value -= unit_value if attributes["exclusiveMaximum"]
|
28
|
+
|
29
|
+
if minimum_value = attributes["minimum"]
|
30
|
+
minimum_value += unit_value if attributes["exclusiveMinimum"]
|
31
|
+
if attributes["exclusiveMaximum"]
|
32
|
+
Random.rand(minimum_value...maximum_value)
|
33
|
+
else
|
34
|
+
Random.rand(minimum_value..maximum_value)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
maximum_value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MinItems
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
8
|
+
min_items = attributes.delete("minItems")
|
9
|
+
raise "No minItems keyword given: #{attributes}" unless min_items
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
invalid_param = []
|
13
|
+
|
14
|
+
(min_items - 1).times do
|
15
|
+
invalid_param << JSONSchemer::Fuzz.default_param(attributes)
|
16
|
+
end
|
17
|
+
|
18
|
+
generated_params << invalid_param
|
19
|
+
|
20
|
+
generated_params
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_param(attributes)
|
24
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
25
|
+
min_items = attributes.delete("minItems")
|
26
|
+
raise "No minItems keyword given: #{attributes}" unless min_items
|
27
|
+
|
28
|
+
generated_param = []
|
29
|
+
|
30
|
+
min_items.times do
|
31
|
+
item = JSONSchemer::Fuzz.default_param(attributes)
|
32
|
+
item = "null" if item.nil?
|
33
|
+
generated_param << "null"
|
34
|
+
end
|
35
|
+
|
36
|
+
generated_param
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MinLength
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
min_length = attributes["minLength"]
|
8
|
+
raise "No minLength keyword given: #{attributes}" unless min_length
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
|
12
|
+
generated_params << /\w{1}/.gen * (min_length - 1)
|
13
|
+
|
14
|
+
generated_params
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid_param(attributes)
|
18
|
+
min_length = attributes["minLength"]
|
19
|
+
raise "No minLength keyword given: #{attributes}" unless min_length
|
20
|
+
|
21
|
+
/\w{1}/.gen * min_length
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MinProperties
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
min_properties = attributes["minProperties"]
|
8
|
+
raise "No minProperties keyword given: #{attributes}" unless min_properties
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
invalid_param = {}
|
12
|
+
|
13
|
+
template = valid_param(attributes)
|
14
|
+
template.delete(template.keys.sample)
|
15
|
+
|
16
|
+
[template]
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid_param(attributes)
|
20
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
21
|
+
min_properties = attributes.delete("minProperties")
|
22
|
+
raise "No minProperties keyword given: #{attributes}" unless min_properties
|
23
|
+
|
24
|
+
template = JSONSchemer::Fuzz.default_param(attributes)
|
25
|
+
|
26
|
+
while template.size < min_properties
|
27
|
+
key = /\w+/.gen
|
28
|
+
template[key] = template[template.keys.sample]
|
29
|
+
end
|
30
|
+
|
31
|
+
template
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Minimum
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
minimum_value = attributes["minimum"]
|
8
|
+
raise "No minimum keyword given: #{attributes}" unless minimum_value
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
12
|
+
|
13
|
+
if attributes["exclusiveMinimum"]
|
14
|
+
generated_params.push(minimum_value)
|
15
|
+
else
|
16
|
+
generated_params.push(minimum_value - unit_value)
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
minimum_value = attributes["minimum"]
|
24
|
+
raise "No minimum keyword given: #{attributes}" unless minimum_value
|
25
|
+
|
26
|
+
unit_value = (attributes.key?("type") && attributes["type"] == "integer") ? 1 : 0.1
|
27
|
+
minimum_value += unit_value if attributes["exclusiveMinimum"]
|
28
|
+
|
29
|
+
if maximum_value = attributes["maximum"]
|
30
|
+
if attributes["exclusiveMaximum"]
|
31
|
+
Random.rand(minimum_value...maximum_value)
|
32
|
+
else
|
33
|
+
Random.rand(minimum_value..maximum_value)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
minimum_value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class MultipleOf
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
multiple_of = attributes["multipleOf"]
|
8
|
+
raise "No multipleOf keyword given: #{attributes}" unless multiple_of
|
9
|
+
|
10
|
+
[multiple_of * 0.9]
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_param(attributes)
|
14
|
+
multiple_of = attributes["multipleOf"]
|
15
|
+
raise "No multipleOf keyword given: #{attributes}" unless multiple_of
|
16
|
+
|
17
|
+
string_num = multiple_of.to_s
|
18
|
+
demicals = (string_num.split(".").length == 2) ? string_num.split(".")[-1].length : 0
|
19
|
+
|
20
|
+
multiple_num = ("%.#{demicals}f" % (multiple_of * Random.rand(1..10)))
|
21
|
+
multiple_of.instance_of?(Float) ? multiple_num.to_f : multiple_num.to_i
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Not
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
not_attribute = attributes["not"]
|
8
|
+
raise "No not keyword given: #{attributes}" unless not_attribute
|
9
|
+
|
10
|
+
[JSONSchemer::Fuzz.default_param(not_attribute)]
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_param(attributes)
|
14
|
+
attributes = Marshal.load(Marshal.dump(attributes))
|
15
|
+
not_attribute = attributes.delete("not")
|
16
|
+
raise "No not keyword given: #{attributes}" unless not_attribute
|
17
|
+
|
18
|
+
generated_params = JSONSchemer::Fuzz.generate(not_attribute)
|
19
|
+
|
20
|
+
generated_params.sample
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class OneOf
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
one_of = attributes["oneOf"]
|
8
|
+
raise "No oneOf keyword given: #{attributes}" unless one_of
|
9
|
+
raise "oneOf keyword given, but had no schemas: #{attributes["oneOf"]}" unless one_of.any?
|
10
|
+
|
11
|
+
generated_params = []
|
12
|
+
|
13
|
+
# Either all params need to be invalid, or all need to be valid.
|
14
|
+
# For simplicity, we'll start with all invalid,
|
15
|
+
# but this could be extended to sometimes return all valid.
|
16
|
+
one_of.each do |schema|
|
17
|
+
temp_params = JSONSchemer::Fuzz.generate(schema).reject do |param|
|
18
|
+
::JSONSchemer.schema(attributes).validate(param)
|
19
|
+
end
|
20
|
+
generated_params.concat(temp_params)
|
21
|
+
end
|
22
|
+
|
23
|
+
raise "failed to generate invalid_params for schema: #{attributes}" if generated_params.empty?
|
24
|
+
[generated_params.uniq.sample]
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid_param(attributes)
|
28
|
+
one_of = attributes["oneOf"]
|
29
|
+
raise "No oneOf keyword given: #{attributes}" unless one_of
|
30
|
+
raise "oneOf keyword given, but had no schemas: #{attributes["oneOf"]}" unless one_of.any?
|
31
|
+
|
32
|
+
generated_params = []
|
33
|
+
|
34
|
+
# Only one of the oneOf can be valid, the others must not be, as it is an XOR
|
35
|
+
# If one of the oneOf's is required,
|
36
|
+
# then then match for that schema cannot also match the other schemas.
|
37
|
+
required_schema_index = one_of.index { |oof| oof["required"] }
|
38
|
+
required_schema = one_of.delete_at(required_schema_index)
|
39
|
+
if required_schema
|
40
|
+
valid_required_param = JSONSchemer::Fuzz.default_param(required_schema).detect do |param|
|
41
|
+
::JSONSchemer.schema(attributes).validate(param)
|
42
|
+
end
|
43
|
+
if valid_required_param
|
44
|
+
generated_params << valid_required_param
|
45
|
+
else
|
46
|
+
one_of.each do |schema|
|
47
|
+
temp_param = JSONSchemer::Fuzz.generate(schema).detect do |param|
|
48
|
+
::JSONSchemer.schema(attributes).validate(param)
|
49
|
+
end
|
50
|
+
if temp_param
|
51
|
+
generated_params << temp_param
|
52
|
+
else
|
53
|
+
# Allow to drop through to attempt to find another part of the oneOf to satisfy
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
return generated_params.uniq.sample if generated_params.any?
|
60
|
+
|
61
|
+
one_of.each do |schema|
|
62
|
+
generated_params.concat(JSONSchemer::Fuzz.generate(schema).select do |param|
|
63
|
+
::JSONSchemer.schema(attributes).validate(param)
|
64
|
+
end)
|
65
|
+
end
|
66
|
+
|
67
|
+
raise "failed to generate invalid_params for schema: #{attributes}" if generated_params.empty?
|
68
|
+
generated_params.uniq.sample
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Pattern
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
raise "not implemented"
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid_param(attributes)
|
11
|
+
raise "not implemented"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module JSONSchemer
|
2
|
+
module Fuzz
|
3
|
+
class Keyword
|
4
|
+
class Properties
|
5
|
+
class << self
|
6
|
+
def invalid_params(attributes)
|
7
|
+
properties = attributes["members"] || attributes["properties"]
|
8
|
+
raise "No properties or members keyword given: #{attributes}" unless properties
|
9
|
+
|
10
|
+
generated_params = []
|
11
|
+
|
12
|
+
properties.each do |key, attribute|
|
13
|
+
JSONSchemer::Fuzz.generate(attribute).each do |invalid_param|
|
14
|
+
template = JSONSchemer::Fuzz.default_param(attributes)
|
15
|
+
generated_params << template.merge(key => invalid_param)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
generated_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid_param(attributes)
|
23
|
+
properties = attributes["members"] || attributes["properties"]
|
24
|
+
raise "No properties or members keyword given: #{attributes}" unless properties
|
25
|
+
|
26
|
+
generated_param = {}
|
27
|
+
|
28
|
+
properties.each do |key, attribute|
|
29
|
+
generated_param[key] = JSONSchemer::Fuzz.default_param(attribute)
|
30
|
+
end
|
31
|
+
|
32
|
+
generated_param
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|