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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08353dd154630cdb6bf5f4707a318a517d6c8823d3aac68d873573e06be06a5a'
4
- data.tar.gz: 621e2214e475cf5980fcc3230b112599a4898e042e0fbacb0c788ca0fc7c7b93
3
+ metadata.gz: cc0fdee0ca3b32ea585dbc281829c47c06d03e8f3206ce657efd4eafcf43aaa2
4
+ data.tar.gz: e2a9f85044898fa8e901813d57d089f16a47c1d453480b66d102cdc4caaef6d0
5
5
  SHA512:
6
- metadata.gz: a2fbac9102de57fe22c2c92a4cde52de9c9b9733d5095ee3ec80c49552179a897e46fa356d62acc9c94e4c82b0cee24bc4c0458c463ca0d30a7f0cdb762306af
7
- data.tar.gz: a81648f6dd527a930e7f77d14af2b6dd30b6e27b2bf14ded042b10aadb45379938bdf607143ff69c9e3b4fa7e5af3dd16fd5119df4bb72f12f0903b251b206ae
6
+ metadata.gz: ff61efb91b1756db9388a7d73eb68f38a971564508ff26b8f1e088c9e0098dde2ac060959a878c018532bb42e93094ba2b3467fc8000bb3ca44ebc8ae9599f70
7
+ data.tar.gz: b34b542836b14d6b211306218bad97298bb2ead2030bcbf23d0ebc8232f508204c0a1f8d34d1840c4fa17e1af8e3f80681ce9feede4f715c7ee5d8ebac9f8916
@@ -119,3 +119,9 @@ RSpec/MessageSpies:
119
119
 
120
120
  RSpec/Pending:
121
121
  Enabled: true
122
+
123
+ Metrics/MethodLength:
124
+ Max: 58
125
+
126
+ Naming/AccessorMethodName:
127
+ Enabled: false
data/README.md CHANGED
@@ -29,11 +29,66 @@ Jfuzz.fuzz(schema_path)
29
29
 
30
30
  ### Configuration
31
31
 
32
- TODO Describe how to change config
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
- TODO Describe how to add/edit generators
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/[USERNAME]/jfuzz.
101
+ Bug reports and pull requests are welcome on GitHub at https://github.com/georgea93/jfuzz.
47
102
 
48
103
 
49
104
  ## License
@@ -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.2"
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
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/module/delegation'
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
- SchemaFuzzer.new(schema_path).fuzz
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
@@ -11,7 +11,7 @@ module Jfuzz
11
11
  @min_integer = 0
12
12
  @max_integer = 0
13
13
  @min_array_length = 0
14
- @max_array_length = 0
14
+ @max_array_length = 0
15
15
  end
16
16
 
17
17
  attr_reader :generators
@@ -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.kind_of?(Array)
13
- return tuple_array
14
- end
10
+ return tuple_array if items.is_a?(Array)
15
11
  random_array
16
12
  end
17
13
 
@@ -5,9 +5,7 @@ require "jfuzz/generators/generator"
5
5
  module Jfuzz
6
6
  class BooleanGenerator < Generator
7
7
  def generate
8
- if rand < Jfuzz.true_probability
9
- return true
10
- end
8
+ return true if rand < Jfuzz.true_probability
11
9
  false
12
10
  end
13
11
 
@@ -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
- min + 1
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 = min / factor
37
- max = max / factor
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
- min + 0.1
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 = min / factor
37
- max = max / factor
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
- CHARSET = Array('A'..'Z') + Array('a'..'z') + Array(0..9)
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 = case format
39
- when DATE
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
- raise "No generator for type #{type}"
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
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jfuzz
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
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.1.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-13 00:00:00.000000000 Z
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.2'
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.2'
26
+ version: '5.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json_schema
29
29
  requirement: !ruby/object:Gem::Requirement