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 +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +27 -8
- data/bin/fakeit +5 -3
- data/docs/random.md +4 -2
- data/docs/static.md +2 -0
- data/lib/fakeit/app/options.rb +8 -2
- data/lib/fakeit/openapi/example/array_example.rb +5 -1
- data/lib/fakeit/openapi/example/boolean_example.rb +1 -1
- data/lib/fakeit/openapi/example/integer_example.rb +5 -1
- data/lib/fakeit/openapi/example/number_example.rb +5 -1
- data/lib/fakeit/openapi/example/object_example.rb +3 -1
- data/lib/fakeit/openapi/example/string_example.rb +19 -8
- data/lib/fakeit/openapi/loader.rb +2 -2
- data/lib/fakeit/openapi/operation.rb +1 -1
- data/lib/fakeit/openapi/schema.rb +18 -4
- data/lib/fakeit/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9828311f1d6fb26ae16bf4bf4ec2fc5c52f5f88bfcdfc3df9ff4b9192671bf06
|
4
|
+
data.tar.gz: 6c739c443ae6506a9584ae8f41f37db3821ef7fc8533321bfdb762ef5d29a0ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af522acb4552e1f45a6595a55aa1159ecf875813ac5547580fee0bd1a9962dfec73e58cc7f02cb53a0398b296537aca72f1cd733d2fbf0241994e9caf391e549
|
7
|
+
data.tar.gz: 9d0ddac0516f7019bb8459172f72570aa2d670d3aca019ac31deec62b165246438b1c0df3f1305a5ab6c9dd28344d195bf389a86b54150db00e3b5d14e90d058
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fakeit (0.
|
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.
|
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.
|
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
|
38
|
-
-p, --port
|
39
|
-
-q, --quiet
|
40
|
-
--permissive
|
41
|
-
--use-example
|
42
|
-
|
43
|
-
|
44
|
-
--static
|
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
|
|
data/docs/random.md
CHANGED
@@ -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:
|
25
|
-
| |maximum|Default:
|
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| |
|
data/docs/static.md
CHANGED
@@ -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|
|
data/lib/fakeit/app/options.rb
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
module Fakeit
|
2
2
|
module App
|
3
3
|
class Options
|
4
|
-
attr_reader :permissive, :use_example
|
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[:
|
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[:
|
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[:
|
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[:
|
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({})
|
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[:
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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'
|
17
|
+
when '.json'
|
18
18
|
JSON.method(:parse)
|
19
|
-
when '.yml', '.yaml'
|
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,
|
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[:
|
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
|
-
|
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
|
data/lib/fakeit/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2019-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|