jfuzz 0.1.0 → 0.2.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 +4 -4
- data/.rubocop.yml +6 -0
- data/README.md +58 -3
- data/jfuzz.gemspec +1 -1
- data/lib/jfuzz.rb +3 -4
- data/lib/jfuzz/configuration.rb +1 -1
- data/lib/jfuzz/generators/array_generator.rb +2 -6
- data/lib/jfuzz/generators/boolean_generator.rb +1 -3
- data/lib/jfuzz/generators/integer_generator.rb +7 -15
- data/lib/jfuzz/generators/number_generator.rb +7 -15
- data/lib/jfuzz/generators/string_generator.rb +16 -21
- data/lib/jfuzz/property_fuzzer.rb +3 -7
- data/lib/jfuzz/schema_fuzzer.rb +14 -4
- data/lib/jfuzz/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc0fdee0ca3b32ea585dbc281829c47c06d03e8f3206ce657efd4eafcf43aaa2
|
4
|
+
data.tar.gz: e2a9f85044898fa8e901813d57d089f16a47c1d453480b66d102cdc4caaef6d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff61efb91b1756db9388a7d73eb68f38a971564508ff26b8f1e088c9e0098dde2ac060959a878c018532bb42e93094ba2b3467fc8000bb3ca44ebc8ae9599f70
|
7
|
+
data.tar.gz: b34b542836b14d6b211306218bad97298bb2ead2030bcbf23d0ebc8232f508204c0a1f8d34d1840c4fa17e1af8e3f80681ce9feede4f715c7ee5d8ebac9f8916
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -29,11 +29,66 @@ Jfuzz.fuzz(schema_path)
|
|
29
29
|
|
30
30
|
### Configuration
|
31
31
|
|
32
|
-
|
32
|
+
#### Nil Probability
|
33
|
+
|
34
|
+
This determines how often we leave out optional fields. The default is `0.2` meaning we will leave out optional fields 20% of the time. It can be changed by:
|
35
|
+
|
36
|
+
```
|
37
|
+
Jfuzz.set_nil_probability(0.5)
|
38
|
+
```
|
39
|
+
|
40
|
+
#### True Probability
|
41
|
+
|
42
|
+
This determines how likely a boolean type is to have a true value. The default is `0.5`
|
43
|
+
|
44
|
+
```
|
45
|
+
Jfuzz.set_true_probability(0.5)
|
46
|
+
```
|
47
|
+
|
48
|
+
|
49
|
+
#### Min/Max Integer/Number values
|
50
|
+
|
51
|
+
You can change the min and max values of integers/numbers that are used when no minimums or maximums are supplied in your schema. The defaults are: -9999999 and 9999999.
|
52
|
+
|
53
|
+
```
|
54
|
+
Jfuzz.set_min_integer(10)
|
55
|
+
Jfuzz.set_max_integer(100)
|
56
|
+
```
|
57
|
+
|
58
|
+
#### Min/Max Array Lengths
|
59
|
+
|
60
|
+
You can change the min and max length of arrays. These are used to generate a random length for an array when you do no specify a min or a max length in you schema. The defaults are 1 and 100
|
61
|
+
|
62
|
+
```
|
63
|
+
Jfuzz.set_min_array_length(10)
|
64
|
+
Jfuzz.set_max_array_length(100)
|
65
|
+
```
|
33
66
|
|
34
67
|
### Generators
|
35
68
|
|
36
|
-
|
69
|
+
If you want custom behaviour when fuzzing a particular type, you can change our built in default generators. This is also useful if you want to add support for your own custom type. First you must define a generator class, e.g. lets say we want to do our own string generation logic:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
require "jfuzz/generators/generator"
|
73
|
+
|
74
|
+
class BetterStringGenerator < Jfuzz::Generator
|
75
|
+
def generate
|
76
|
+
"AMAZING STRING"
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.type
|
80
|
+
"string"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
Finally you need to register the generator with JFuzz by doing the following:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
Jfuzz.register_generator(BetterStringGenerator)
|
89
|
+
```
|
90
|
+
|
91
|
+
Note. You will need to register your new generator before calling `Jfuzz.fuzz`
|
37
92
|
|
38
93
|
## Development
|
39
94
|
|
@@ -43,7 +98,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
43
98
|
|
44
99
|
## Contributing
|
45
100
|
|
46
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
101
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/georgea93/jfuzz.
|
47
102
|
|
48
103
|
|
49
104
|
## License
|
data/jfuzz.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_dependency "activesupport", "~> 5.
|
25
|
+
spec.add_dependency "activesupport", "~> 5.1"
|
26
26
|
spec.add_dependency "json_schema", "~> 0.17"
|
27
27
|
spec.add_dependency "regexp-examples", "~> 1.4"
|
28
28
|
|
data/lib/jfuzz.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
4
|
|
5
5
|
require "jfuzz/version"
|
6
6
|
require "jfuzz/configuration"
|
@@ -13,14 +13,13 @@ require "jfuzz/generators/object_generator"
|
|
13
13
|
require "jfuzz/generators/array_generator"
|
14
14
|
require "jfuzz/generators/string_generator"
|
15
15
|
|
16
|
-
|
17
16
|
module Jfuzz
|
18
17
|
def self.configuration
|
19
18
|
@configuration ||= Configuration.new
|
20
19
|
end
|
21
20
|
|
22
21
|
def self.fuzz(schema_path)
|
23
|
-
|
22
|
+
SchemaFuzzer.new(schema_path).fuzz
|
24
23
|
end
|
25
24
|
|
26
25
|
class << self
|
@@ -46,7 +45,7 @@ module Jfuzz
|
|
46
45
|
def self.set_true_probability(val)
|
47
46
|
configuration.true_probability = val
|
48
47
|
end
|
49
|
-
|
48
|
+
|
50
49
|
def self.set_min_integer(val)
|
51
50
|
configuration.min_integer = val
|
52
51
|
end
|
data/lib/jfuzz/configuration.rb
CHANGED
@@ -5,13 +5,9 @@ require "jfuzz/generators/generator"
|
|
5
5
|
module Jfuzz
|
6
6
|
class ArrayGenerator < Generator
|
7
7
|
def generate
|
8
|
-
unless items.any?
|
9
|
-
raise "Cannot generate an empty array. Please specify item types"
|
10
|
-
end
|
8
|
+
raise "Cannot generate an empty array. Please specify item types" unless items.any?
|
11
9
|
|
12
|
-
if items.
|
13
|
-
return tuple_array
|
14
|
-
end
|
10
|
+
return tuple_array if items.is_a?(Array)
|
15
11
|
random_array
|
16
12
|
end
|
17
13
|
|
@@ -8,7 +8,7 @@ module Jfuzz
|
|
8
8
|
def generate
|
9
9
|
random_integer
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def self.type
|
13
13
|
"integer"
|
14
14
|
end
|
@@ -18,12 +18,8 @@ module Jfuzz
|
|
18
18
|
def random_integer
|
19
19
|
min = minimum
|
20
20
|
max = maximum
|
21
|
-
if exclusive_minimum?
|
22
|
-
|
23
|
-
end
|
24
|
-
if exclusive_maximum?
|
25
|
-
max - 1
|
26
|
-
end
|
21
|
+
min + 1 if exclusive_minimum?
|
22
|
+
max - 1 if exclusive_maximum?
|
27
23
|
|
28
24
|
return generate_multiple(min, max) if multiple_of?
|
29
25
|
|
@@ -33,22 +29,18 @@ module Jfuzz
|
|
33
29
|
def generate_multiple(min, max)
|
34
30
|
factor = property.fetch("multipleOf").to_i
|
35
31
|
|
36
|
-
min
|
37
|
-
max
|
32
|
+
min /= factor
|
33
|
+
max /= factor
|
38
34
|
rand(min..max).to_i * factor
|
39
35
|
end
|
40
36
|
|
41
37
|
def minimum
|
42
|
-
if minimum?
|
43
|
-
return property.fetch("minimum").to_i
|
44
|
-
end
|
38
|
+
return property.fetch("minimum").to_i if minimum?
|
45
39
|
Jfuzz.min_integer.to_i
|
46
40
|
end
|
47
41
|
|
48
42
|
def maximum
|
49
|
-
if maximum?
|
50
|
-
return property.fetch("maximum").to_i
|
51
|
-
end
|
43
|
+
return property.fetch("maximum").to_i if maximum?
|
52
44
|
Jfuzz.max_integer.to_i
|
53
45
|
end
|
54
46
|
|
@@ -8,7 +8,7 @@ module Jfuzz
|
|
8
8
|
def generate
|
9
9
|
random_number
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def self.type
|
13
13
|
"number"
|
14
14
|
end
|
@@ -18,12 +18,8 @@ module Jfuzz
|
|
18
18
|
def random_number
|
19
19
|
min = minimum
|
20
20
|
max = maximum
|
21
|
-
if exclusive_minimum?
|
22
|
-
|
23
|
-
end
|
24
|
-
if exclusive_maximum?
|
25
|
-
max - 0.1
|
26
|
-
end
|
21
|
+
min + 0.1 if exclusive_minimum?
|
22
|
+
max - 0.1 if exclusive_maximum?
|
27
23
|
|
28
24
|
return generate_multiple(min, max) if multiple_of?
|
29
25
|
|
@@ -33,22 +29,18 @@ module Jfuzz
|
|
33
29
|
def generate_multiple(min, max)
|
34
30
|
factor = property.fetch("multipleOf").to_f
|
35
31
|
|
36
|
-
min
|
37
|
-
max
|
32
|
+
min /= factor
|
33
|
+
max /= factor
|
38
34
|
rand(min..max).to_i * factor
|
39
35
|
end
|
40
36
|
|
41
37
|
def minimum
|
42
|
-
if minimum?
|
43
|
-
return property.fetch("minimum").to_f
|
44
|
-
end
|
38
|
+
return property.fetch("minimum").to_f if minimum?
|
45
39
|
Jfuzz.min_integer.to_f
|
46
40
|
end
|
47
41
|
|
48
42
|
def maximum
|
49
|
-
if maximum?
|
50
|
-
return property.fetch("maximum").to_f
|
51
|
-
end
|
43
|
+
return property.fetch("maximum").to_f if maximum?
|
52
44
|
Jfuzz.max_integer.to_f
|
53
45
|
end
|
54
46
|
|
@@ -4,14 +4,21 @@ require "regexp-examples"
|
|
4
4
|
require "date"
|
5
5
|
require "jfuzz/generators/generator"
|
6
6
|
|
7
|
-
module Jfuzz
|
7
|
+
module Jfuzz
|
8
8
|
class StringGenerator < Generator
|
9
|
-
|
10
9
|
DATE = "date"
|
11
|
-
TIME = "time"
|
12
10
|
DATE_TIME = "date-time"
|
13
11
|
|
14
|
-
|
12
|
+
DATE_REGEXP = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/
|
13
|
+
TIME_REGEXP = /\A(\d{2}):(\d{2}):(\d{2})\z/
|
14
|
+
DATE_TIME_REGEXP = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-2][0-9]:[0-5][0-9]:[0-5][0-9](\.[0-9]+)?(Z|[\-+][0-9]{2}:[0-5][0-9])$/
|
15
|
+
|
16
|
+
FORMATS = {
|
17
|
+
DATE => DATE_REGEXP,
|
18
|
+
DATE_TIME => DATE_TIME_REGEXP,
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
CHARSET = Array("A".."Z") + Array("a".."z") + Array(0..9)
|
15
22
|
|
16
23
|
def generate
|
17
24
|
if format?
|
@@ -34,30 +41,18 @@ module Jfuzz
|
|
34
41
|
Array.new(length) { CHARSET.sample }.join
|
35
42
|
end
|
36
43
|
|
44
|
+
# rubocop:disable Metrics/AbcSize
|
37
45
|
def generate_from_format
|
38
|
-
str =
|
39
|
-
|
40
|
-
Time.at(rand * Time.now.to_i).to_date.to_s
|
41
|
-
when TIME
|
42
|
-
Time.at(rand * Time.now.to_i).to_datetime.to_s
|
43
|
-
when DATE_TIME
|
44
|
-
Time.at(rand * Time.now.to_i).to_s
|
45
|
-
else
|
46
|
-
raise "Unsupported format: #{format}"
|
47
|
-
end
|
48
|
-
|
49
|
-
if max_length?
|
50
|
-
return str[0..max_length - 1]
|
51
|
-
end
|
46
|
+
str = FORMATS[format].random_example
|
47
|
+
return str[0..max_length - 1] if max_length?
|
52
48
|
str
|
53
49
|
end
|
50
|
+
# rubocop:enable Metrics/AbcSize
|
54
51
|
|
55
52
|
def generate_from_pattern
|
56
53
|
str = Regexp.new(pattern).random_example
|
57
54
|
|
58
|
-
if max_length?
|
59
|
-
return str[0..max_length - 1]
|
60
|
-
end
|
55
|
+
return str[0..max_length - 1] if max_length?
|
61
56
|
str
|
62
57
|
end
|
63
58
|
|
@@ -6,10 +6,8 @@ module Jfuzz
|
|
6
6
|
type = type(property)
|
7
7
|
|
8
8
|
generator = Jfuzz.generators.fetch(type, nil)
|
9
|
-
if generator.nil?
|
10
|
-
|
11
|
-
end
|
12
|
-
|
9
|
+
raise "No generator for type #{type}" if generator.nil?
|
10
|
+
|
13
11
|
generator.new(property, self).try_generate
|
14
12
|
end
|
15
13
|
|
@@ -18,9 +16,7 @@ module Jfuzz
|
|
18
16
|
def type(property)
|
19
17
|
t = property["type"]
|
20
18
|
|
21
|
-
if enum?(property)
|
22
|
-
t = "enum"
|
23
|
-
end
|
19
|
+
t = "enum" if enum?(property)
|
24
20
|
t
|
25
21
|
end
|
26
22
|
|
data/lib/jfuzz/schema_fuzzer.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "json"
|
4
|
+
require "json_schema"
|
4
5
|
require "jfuzz/property_fuzzer"
|
5
6
|
|
6
7
|
module Jfuzz
|
@@ -11,14 +12,23 @@ module Jfuzz
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def fuzz
|
14
|
-
if schema_path.to_s.nil?
|
15
|
-
raise "Schema path cannot be nil or empty"
|
16
|
-
end
|
15
|
+
raise "Schema path cannot be nil or empty" if schema_path.to_s.nil?
|
17
16
|
|
18
17
|
schema_contents = File.read(schema_path)
|
19
18
|
schema = JSON.parse(schema_contents)
|
20
19
|
|
21
|
-
property_fuzzer.fuzz_property(schema)
|
20
|
+
fuzzed = property_fuzzer.fuzz_property(schema)
|
21
|
+
|
22
|
+
json_schema = JsonSchema.parse!(schema)
|
23
|
+
is_valid, validation_errors = json_schema.validate(fuzzed)
|
24
|
+
|
25
|
+
unless is_valid
|
26
|
+
raise "Error in the report validation. Produced invalid JSON file " \
|
27
|
+
"according to JSON schema #{schema_path}. " \
|
28
|
+
"Validation errors: #{validation_errors}"
|
29
|
+
end
|
30
|
+
|
31
|
+
fuzzed
|
22
32
|
end
|
23
33
|
|
24
34
|
private
|
data/lib/jfuzz/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jfuzz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- George Allen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '5.
|
19
|
+
version: '5.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '5.
|
26
|
+
version: '5.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json_schema
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|