fakeit 0.2.1 → 0.3.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: 46f41bf28d7b4e0775fe84baa2d134947daa0e1ab114c4ad92bc95f63dc678be
4
- data.tar.gz: ba497fcaf61e251e0316f7ac86223d84550f0c74d35db9319d3b152061de557b
3
+ metadata.gz: 9828311f1d6fb26ae16bf4bf4ec2fc5c52f5f88bfcdfc3df9ff4b9192671bf06
4
+ data.tar.gz: 6c739c443ae6506a9584ae8f41f37db3821ef7fc8533321bfdb762ef5d29a0ed
5
5
  SHA512:
6
- metadata.gz: b7579ea64592fb2106a6a4af5d747f49be9eca739410a0decc0efb97fab22813a59cf416b57f13cfbc3ae0487449e7e1a5350533c98581baaa078d2266e80689
7
- data.tar.gz: 42f1b09134e6f67cd933df04c00f9a154888830f500fd4d78a68bef780721d8f70f0409ee1a4d756640f5505783b2539d5856759f9096ff844fba5a023fdc843
6
+ metadata.gz: af522acb4552e1f45a6595a55aa1159ecf875813ac5547580fee0bd1a9962dfec73e58cc7f02cb53a0398b296537aca72f1cd733d2fbf0241994e9caf391e549
7
+ data.tar.gz: 9d0ddac0516f7019bb8459172f72570aa2d670d3aca019ac31deec62b165246438b1c0df3f1305a5ab6c9dd28344d195bf389a86b54150db00e3b5d14e90d058
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fakeit (0.2.1)
4
+ fakeit (0.3.0)
5
5
  faker (~> 1.9)
6
6
  openapi_parser (= 0.3.1)
7
7
  rack (~> 2.0)
@@ -31,7 +31,7 @@ GEM
31
31
  rack-test (1.1.0)
32
32
  rack (>= 1.0, < 3)
33
33
  rainbow (3.0.0)
34
- rake (12.3.2)
34
+ rake (12.3.3)
35
35
  rspec (3.8.0)
36
36
  rspec-core (~> 3.8.0)
37
37
  rspec-expectations (~> 3.8.0)
@@ -45,7 +45,7 @@ GEM
45
45
  diff-lcs (>= 1.2.0, < 2.0)
46
46
  rspec-support (~> 3.8.0)
47
47
  rspec-support (3.8.2)
48
- rubocop (0.72.0)
48
+ rubocop (0.74.0)
49
49
  jaro_winkler (~> 1.5.1)
50
50
  parallel (~> 1.10)
51
51
  parser (>= 2.6)
data/README.md CHANGED
@@ -9,6 +9,25 @@
9
9
 
10
10
  Create mock server from Openapi specification
11
11
 
12
+ ## Motivation
13
+
14
+ Openapi mock server is one of core components to support contract based development and testing. As part of our journal, several key requirements for such mock server have been identified:
15
+
16
+ * Control response generation in non intrusive manner. i.e. without modifying example in contract
17
+ * Randomly generated response to support property based testing
18
+ * Fulfill property reference in response generation to support development against contract. i.e. regarding the following response, guarantee the `selectedId` property is always a valid `id` in the items
19
+ ```json
20
+ {
21
+ "selectedId": 1,
22
+ "items": [
23
+ { "id": 1 },
24
+ { "id": 2 }
25
+ ]
26
+ }
27
+ ```
28
+
29
+ After tried several existing options, we cannot find a best solution to meet all the requirements. So we decide to __'Fakeit till you make it'__.
30
+
12
31
  ## Features
13
32
 
14
33
  * Randomly or statically generated response
@@ -34,14 +53,14 @@ Command line options:
34
53
 
35
54
  $ fakeit --help
36
55
  usage:
37
- --spec spec file uri (required)
38
- -p, --port custom port
39
- -q, --quiet mute request and response log
40
- --permissive log validation error as warning instead of denying request
41
- --use-example use example provided in spec if exists
42
-
43
- trial options:
44
- --static generate static response
56
+ --spec spec file uri (required)
57
+ -p, --port custom port
58
+ -q, --quiet mute request and response log
59
+ --permissive log validation error as warning instead of denying request
60
+ --use-example use example provided in spec if exists
61
+ --static generate static response
62
+ --static-types generate static value for specified types, e.g. --static-types integer,string
63
+ --static-properties generate static value for specified properties, e.g. --static-types id,uuid
45
64
 
46
65
  other options:
47
66
  -v, --version
data/bin/fakeit CHANGED
@@ -12,9 +12,9 @@ begin
12
12
  o.bool '-q', '--quiet', 'mute request and response log'
13
13
  o.bool '--permissive', 'log validation error as warning instead of denying request'
14
14
  o.bool '--use-example', 'use example provided in spec if exists'
15
- o.separator ''
16
- o.separator 'trial options:'
17
15
  o.bool '--static', 'generate static response'
16
+ o.array '--static-types', 'generate static value for specified types, e.g. --static-types integer,string'
17
+ o.array '--static-properties', 'generate static value for specified properties, e.g. --static-types id,uuid'
18
18
  o.separator ''
19
19
  o.separator 'other options:'
20
20
  o.on '-v', '--version' do
@@ -47,7 +47,9 @@ end
47
47
  options = Fakeit::App::Options.new(
48
48
  permissive: opts.permissive?,
49
49
  use_example: opts.use_example?,
50
- static: opts.static?
50
+ static: opts.static?,
51
+ static_types: opts[:static_types],
52
+ static_properties: opts[:static_properties]
51
53
  )
52
54
  app = Fakeit.build(opts[:spec], options)
53
55
 
@@ -21,11 +21,13 @@ The following Openapi properties are supported in random response generation
21
21
  | |minLength|Default: `0`|
22
22
  | |maxLength|Default: `minLength + 10`|
23
23
  |integer|enum| |
24
- | |minimum|Default: `-2^31`|
25
- | |maximum|Default: `2^31 - 1`|
24
+ | |minimum|Default: based on format|
25
+ | |maximum|Default: based on format|
26
26
  | |exclusiveMinimum| |
27
27
  | |exclusiveMaximum| |
28
28
  | |multipleOf| |
29
+ | |format=int32|`-2^31` ~ `2^31 - 1`|
30
+ | |format=int64|`-2^63` ~ `2^63 - 1`|
29
31
  |number|minimum|Default: `-2^31`|
30
32
  | |maximum|Default: `2^31 - 1`|
31
33
  | |multipleOf| |
@@ -24,6 +24,8 @@ Static value generation rule
24
24
  | |maximum|maximum|
25
25
  | |exclusiveMaximum|maximum - 1|
26
26
  | |multipleOf|maximum value meets multipleOf condition|
27
+ | |format=int32|`2^31 - 1`|
28
+ | |format=int64|`2^63 - 1`|
27
29
  |number|N/A|`2^31 - 1`|
28
30
  | |maximum|maximum rounded to 2 decimal places|
29
31
  | |multipleOf|maximum value meets multipleOf condition|
@@ -1,12 +1,18 @@
1
1
  module Fakeit
2
2
  module App
3
3
  class Options
4
- attr_reader :permissive, :use_example, :static
4
+ attr_reader :permissive, :use_example
5
5
 
6
- def initialize(permissive: false, use_example: false, static: false)
6
+ def initialize(permissive: false, use_example: false, static: false, static_types: [], static_properties: [])
7
7
  @permissive = permissive
8
8
  @use_example = use_example
9
9
  @static = static
10
+ @static_types = static_types
11
+ @static_properties = static_properties
12
+ end
13
+
14
+ def use_static?(type: nil, property: nil)
15
+ @static || @static_types.include?(type) || @static_properties.include?(property)
10
16
  end
11
17
  end
12
18
  end
@@ -3,7 +3,11 @@ module Fakeit
3
3
  module Example
4
4
  def array_example(options)
5
5
  example_options = add_depth(options)
6
- example_options[:static] ? static_array_example(example_options) : random_array_example(example_options)
6
+ if example_options[:use_static][type: 'array', property: example_options[:property]]
7
+ static_array_example(example_options)
8
+ else
9
+ random_array_example(example_options)
10
+ end
7
11
  end
8
12
 
9
13
  private
@@ -2,7 +2,7 @@ module Fakeit
2
2
  module Openapi
3
3
  module Example
4
4
  def boolean_example(example_options)
5
- example_options[:static] || Faker::Boolean.boolean
5
+ example_options[:use_static][type: 'boolean', property: example_options[:property]] || Faker::Boolean.boolean
6
6
  end
7
7
  end
8
8
  end
@@ -2,7 +2,11 @@ module Fakeit
2
2
  module Openapi
3
3
  module Example
4
4
  def integer_example(example_options)
5
- example_options[:static] ? static_integer_example : random_integer_example
5
+ if example_options[:use_static][type: 'integer', property: example_options[:property]]
6
+ static_integer_example
7
+ else
8
+ random_integer_example
9
+ end
6
10
  end
7
11
 
8
12
  private
@@ -5,7 +5,11 @@ module Fakeit
5
5
  MAX_NUM = 2**31 - 1
6
6
 
7
7
  def number_example(example_options)
8
- example_options[:static] ? static_number_example : random_number_example
8
+ if example_options[:use_static][type: 'number', property: example_options[:property]]
9
+ static_number_example
10
+ else
11
+ random_number_example
12
+ end
9
13
  end
10
14
 
11
15
  private
@@ -2,7 +2,9 @@ module Fakeit
2
2
  module Openapi
3
3
  module Example
4
4
  def object_example(example_options)
5
- properties.each_with_object({}) { |(name, schema), obj| obj[name] = schema.to_example(example_options) }
5
+ properties.each_with_object({}) do |(name, schema), obj|
6
+ obj[name] = schema.to_example(example_options.merge(property: name))
7
+ end
6
8
  end
7
9
  end
8
10
  end
@@ -23,22 +23,33 @@ module Fakeit
23
23
  }.freeze
24
24
 
25
25
  def string_example(example_options)
26
- example_options[:static] ? static_string_example : random_string_example
26
+ if example_options[:use_static][type: 'string', property: example_options[:property]]
27
+ static_string_example
28
+ else
29
+ random_string_example
30
+ end
27
31
  end
28
32
 
29
33
  private
30
34
 
31
35
  def static_string_example
32
- Faker::Config.random = Random.new(1) # Fix seed for faker
33
-
34
- if enum then enum.to_a.first
35
- elsif pattern then Faker::Base.regexify(pattern)
36
- elsif format then static_string_format
37
- elsif length_constraint then static_string_with_length
38
- else 'string'
36
+ fixed_faker do
37
+ if enum then enum.to_a.first
38
+ elsif pattern then Faker::Base.regexify(pattern)
39
+ elsif format then static_string_format
40
+ elsif length_constraint then static_string_with_length
41
+ else 'string'
42
+ end
39
43
  end
40
44
  end
41
45
 
46
+ def fixed_faker(&block)
47
+ Faker::Config.random = Random.new(1)
48
+ result = block.call
49
+ Faker::Config.random = nil
50
+ result
51
+ end
52
+
42
53
  def random_string_example
43
54
  if enum then enum.to_a.sample
44
55
  elsif pattern then Faker::Base.regexify(pattern)
@@ -14,9 +14,9 @@ module Fakeit
14
14
 
15
15
  def parse_method(src)
16
16
  case File.extname(src)
17
- when '.json' then
17
+ when '.json'
18
18
  JSON.method(:parse)
19
- when '.yml', '.yaml' then
19
+ when '.yml', '.yaml'
20
20
  YAML.method(:safe_load)
21
21
  else
22
22
  raise 'Invalid openapi specification file'
@@ -33,7 +33,7 @@ module Fakeit
33
33
  private
34
34
 
35
35
  def example_options
36
- { use_example: @app_options.use_example, static: @app_options.static, depth: 0 }
36
+ { use_example: @app_options.use_example, use_static: @app_options.method(:use_static?), depth: 0 }
37
37
  end
38
38
 
39
39
  def response_content
@@ -23,7 +23,11 @@ module Fakeit
23
23
  private
24
24
 
25
25
  def one_of_example(example_options)
26
- example_options[:static] ? one_of.first.to_example(example_options) : one_of.sample.to_example(example_options)
26
+ if example_options[:use_static][property: example_options[:property]]
27
+ one_of.first.to_example(example_options)
28
+ else
29
+ one_of.sample.to_example(example_options)
30
+ end
27
31
  end
28
32
 
29
33
  def all_of_example(example_options)
@@ -34,13 +38,23 @@ module Fakeit
34
38
  end
35
39
 
36
40
  def any_of_example(example_options)
37
- any_of
38
- .select { |option| option.type == 'object' }
39
- .then { |options| example_options[:static] ? options : options.sample(Faker::Number.between(1, any_of.size)) }
41
+ any_of_options(example_options)
40
42
  .map { |option| option.to_example(example_options) }
41
43
  .reduce(&:merge)
42
44
  end
43
45
 
46
+ def any_of_options(example_options)
47
+ any_of
48
+ .select { |option| option.type == 'object' }
49
+ .then do |options|
50
+ if example_options[:use_static][property: example_options[:property]]
51
+ options
52
+ else
53
+ options.sample(Faker::Number.between(1, any_of.size))
54
+ end
55
+ end
56
+ end
57
+
44
58
  def type_based_example(example_options)
45
59
  send("#{type}_example", example_options) if %w[string integer number boolean array object].include?(type)
46
60
  end
@@ -1,3 +1,3 @@
1
1
  module Fakeit
2
- VERSION = '0.2.1'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fakeit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Feng
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-04 00:00:00.000000000 Z
11
+ date: 2019-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler