fakeit 0.5.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e532a36b31f1e5ae42a1e424d77f8ef336c54d7519bfa7b3223f27d46c7b1a8d
4
- data.tar.gz: dc4e70a6bac2858abc1a251cb2ffe8aff2272ec4926187dd69c19d4ad0be867f
3
+ metadata.gz: 2f19c0713bc918d394d2bb1c56251b09cf6dae231a0252c5bbb32c3b99fd284d
4
+ data.tar.gz: abcb565c1179594b5ea2b5c2f707c4c3597fbb74e2833edeb5335661866723a0
5
5
  SHA512:
6
- metadata.gz: a57970664a9b1e27d0bc8d1a78cea8b4311c0a56b6c3edc252f232728de767c11dea3af0b8419a00e2ce722659f053c2504f8a5432b9cdfe21ab35a77e6c63df
7
- data.tar.gz: f36c7175d63d53f35c0b4de54ec07f0129179cc2f2187d7640c5811ae639084f01f1d5cd80ac08e40a713910f6a3d1c5f440a8be3978772565a444467519d66d
6
+ metadata.gz: 962926947343492b3b37a5e1739d8919cc76ffac8491e033e183f72a8ac2346eb62147aed3e870da9dfc8988422c9f0869255d7957253bb56fc0f35772e8065a
7
+ data.tar.gz: d471fae5943b4932e07413ee8f67ba484f188efddb0a5d4bf8198f0d791eea07e9744514e7b6ef0890be5dd4932a088bd4f9cc60111f9c72adfadfd96af5fb44
@@ -26,3 +26,45 @@ Style/HashTransformKeys:
26
26
 
27
27
  Style/HashTransformValues:
28
28
  Enabled: true
29
+
30
+ Lint/RaiseException:
31
+ Enabled: true
32
+
33
+ Lint/StructNewOverride:
34
+ Enabled: true
35
+
36
+ Layout/EmptyLinesAroundAttributeAccessor:
37
+ Enabled: true
38
+
39
+ Layout/SpaceAroundMethodCallOperator:
40
+ Enabled: true
41
+
42
+ Lint/DeprecatedOpenSSLConstant:
43
+ Enabled: true
44
+
45
+ Lint/MixedRegexpCaptureTypes:
46
+ Enabled: true
47
+
48
+ Style/AccessorGrouping:
49
+ Enabled: true
50
+
51
+ Style/BisectedAttrAccessor:
52
+ Enabled: true
53
+
54
+ Style/ExponentialNotation:
55
+ Enabled: true
56
+
57
+ Style/RedundantAssignment:
58
+ Enabled: true
59
+
60
+ Style/RedundantFetchBlock:
61
+ Enabled: true
62
+
63
+ Style/RedundantRegexpCharacterClass:
64
+ Enabled: true
65
+
66
+ Style/RedundantRegexpEscape:
67
+ Enabled: true
68
+
69
+ Style/SlicingWithRange:
70
+ Enabled: true
@@ -1,67 +1,70 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fakeit (0.5.1)
5
- faker (~> 2.2)
6
- openapi_parser (= 0.8.0)
4
+ fakeit (0.6.2)
5
+ faker (= 2.13.0)
6
+ openapi_parser (= 0.11.2)
7
7
  rack (~> 2.0)
8
8
  rack-cors (~> 1.0)
9
9
  rainbow (~> 3.0)
10
- slop (~> 4.6)
10
+ slop (~> 4.8)
11
11
 
12
12
  GEM
13
13
  remote: https://rubygems.org/
14
14
  specs:
15
- ast (2.4.0)
16
- byebug (11.1.1)
15
+ ast (2.4.1)
16
+ byebug (11.1.3)
17
17
  concurrent-ruby (1.1.6)
18
- diff-lcs (1.3)
18
+ diff-lcs (1.4.4)
19
19
  docile (1.3.2)
20
- faker (2.10.2)
20
+ faker (2.13.0)
21
21
  i18n (>= 1.6, < 2)
22
- i18n (1.8.2)
22
+ i18n (1.8.3)
23
23
  concurrent-ruby (~> 1.0)
24
- jaro_winkler (1.5.4)
25
- openapi_parser (0.8.0)
26
- parallel (1.19.1)
27
- parser (2.7.0.2)
28
- ast (~> 2.4.0)
29
- rack (2.2.2)
24
+ openapi_parser (0.11.2)
25
+ parallel (1.19.2)
26
+ parser (2.7.1.4)
27
+ ast (~> 2.4.1)
28
+ rack (2.2.3)
30
29
  rack-cors (1.1.1)
31
30
  rack (>= 2.0.0)
32
31
  rack-test (1.1.0)
33
32
  rack (>= 1.0, < 3)
34
33
  rainbow (3.0.0)
35
34
  rake (12.3.3)
35
+ regexp_parser (1.7.1)
36
36
  rexml (3.2.4)
37
37
  rspec (3.9.0)
38
38
  rspec-core (~> 3.9.0)
39
39
  rspec-expectations (~> 3.9.0)
40
40
  rspec-mocks (~> 3.9.0)
41
- rspec-core (3.9.1)
42
- rspec-support (~> 3.9.1)
43
- rspec-expectations (3.9.0)
41
+ rspec-core (3.9.2)
42
+ rspec-support (~> 3.9.3)
43
+ rspec-expectations (3.9.2)
44
44
  diff-lcs (>= 1.2.0, < 2.0)
45
45
  rspec-support (~> 3.9.0)
46
46
  rspec-mocks (3.9.1)
47
47
  diff-lcs (>= 1.2.0, < 2.0)
48
48
  rspec-support (~> 3.9.0)
49
- rspec-support (3.9.2)
50
- rubocop (0.80.0)
51
- jaro_winkler (~> 1.5.1)
49
+ rspec-support (3.9.3)
50
+ rubocop (0.87.1)
52
51
  parallel (~> 1.10)
53
- parser (>= 2.7.0.1)
52
+ parser (>= 2.7.1.1)
54
53
  rainbow (>= 2.2.2, < 4.0)
54
+ regexp_parser (>= 1.7)
55
55
  rexml
56
+ rubocop-ast (>= 0.1.0, < 1.0)
56
57
  ruby-progressbar (~> 1.7)
57
- unicode-display_width (>= 1.4.0, < 1.7)
58
+ unicode-display_width (>= 1.4.0, < 2.0)
59
+ rubocop-ast (0.1.0)
60
+ parser (>= 2.7.0.1)
58
61
  ruby-progressbar (1.10.1)
59
- simplecov (0.18.2)
62
+ simplecov (0.18.5)
60
63
  docile (~> 1.1)
61
64
  simplecov-html (~> 0.11)
62
- simplecov-html (0.12.0)
63
- slop (4.8.0)
64
- unicode-display_width (1.6.1)
65
+ simplecov-html (0.12.2)
66
+ slop (4.8.2)
67
+ unicode-display_width (1.7.0)
65
68
 
66
69
  PLATFORMS
67
70
  ruby
data/README.md CHANGED
@@ -30,14 +30,12 @@ After tried several existing options, we cannot find a best solution to meet all
30
30
 
31
31
  ## Features
32
32
 
33
- * Randomly or statically generated response
34
- * Request validation
33
+ * Randomly or statically generated response (`application/.*json`)
34
+ * Request validation (`application/.*json`, `multipart/form-data`)
35
35
  * Load specification from local or remote
36
36
  * Support hot reload local specification
37
37
  * Support specification in yaml or json format
38
38
 
39
- **Note:** Only support json content type as of now
40
-
41
39
  ## Installation
42
40
 
43
41
  Install it with:
@@ -61,7 +59,7 @@ Command line options:
61
59
  --use-example use example provided in spec if exists
62
60
  --static generate static response
63
61
  --static-types generate static value for specified types, e.g. --static-types integer,string
64
- --static-properties generate static value for specified properties, e.g. --static-types id,uuid
62
+ --static-properties generate static value for specified properties, e.g. --static-properties id,uuid
65
63
 
66
64
  other options:
67
65
  -v, --version
@@ -18,7 +18,8 @@ The following Openapi properties are supported in random response generation
18
18
  | |format=email| |
19
19
  | |format=date|In past 100 days|
20
20
  | |format=date-time|In past 100 days|
21
- | |format=binary|Length is a multiple of `4` between `4` ~ `100`|
21
+ | |format=binary|UTF-8 string|
22
+ | |format=byte|Base64 encoded UTF-8 string|
22
23
  | |minLength|Default: `0`|
23
24
  | |maxLength|Default: `minLength + 10`|
24
25
  |integer|enum| |
@@ -6,8 +6,9 @@ Static value generation rule
6
6
  |---|---|---|
7
7
  |complex|oneOf|first item|
8
8
  | |anyOf|same as allOf|
9
+ |boolean|N/A|`true`|
9
10
  |array|N/A|size is `1`|
10
- | |minItems|size is minItems|
11
+ | |minItems|size is max(minItems,1)|
11
12
  |string|N/A|`string`|
12
13
  | |enum|first item|
13
14
  | |pattern|Generated but always the same|
@@ -17,7 +18,8 @@ Static value generation rule
17
18
  | |format=email|`some@email.com`|
18
19
  | |format=date|today|
19
20
  | |format=date-time|midnight today|
20
- | |format=binary|`1111`|
21
+ | |format=binary|`binary`|
22
+ | |format=byte|`Ynl0ZQ==`|
21
23
  | |minLength|`1` repeats for (minLength + 10) times if no maxLength specified|
22
24
  | |maxLength|`1` repeats for maxLength times|
23
25
  |integer|N/A|`2^31 - 1`|
@@ -32,10 +32,10 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency 'rubocop', '~> 0.80'
33
33
  spec.add_development_dependency 'simplecov', '~> 0.18'
34
34
 
35
- spec.add_dependency 'faker', '~> 2.2'
36
- spec.add_dependency 'openapi_parser', '0.8.0'
35
+ spec.add_dependency 'faker', '2.13.0'
36
+ spec.add_dependency 'openapi_parser', '0.11.2'
37
37
  spec.add_dependency 'rack', '~> 2.0'
38
38
  spec.add_dependency 'rack-cors', '~> 1.0'
39
39
  spec.add_dependency 'rainbow', '~> 3.0'
40
- spec.add_dependency 'slop', '~> 4.6'
40
+ spec.add_dependency 'slop', '~> 4.8'
41
41
  end
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'yaml'
3
3
  require 'open-uri'
4
+ require 'base64'
4
5
  require 'openapi_parser'
5
6
  require 'faker'
6
7
  require 'rack'
@@ -36,7 +36,7 @@ module Fakeit
36
36
 
37
37
  def validate(operation, request)
38
38
  operation.validate(
39
- body: request.body&.read.to_s,
39
+ body: BodyParser.parse(request),
40
40
  params: parse_query(request.query_string),
41
41
  headers: headers(request)
42
42
  )
@@ -0,0 +1,30 @@
1
+ module Fakeit
2
+ module App
3
+ class BodyParser
4
+ class << self
5
+ def parse(request)
6
+ case request.media_type
7
+ when %r{^application/.*json}
8
+ { media_type: request.media_type, data: parse_json(request.body.read) }
9
+ when 'multipart/form-data'
10
+ { media_type: request.media_type, data: parse_form_data(request.params) }
11
+ else
12
+ { media_type: request.media_type, data: request.body.read }
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def parse_json(body)
19
+ body.empty? ? {} : JSON.parse(body)
20
+ rescue StandardError
21
+ raise Fakeit::Validation::ValidationError, 'Invalid json payload'
22
+ end
23
+
24
+ def parse_form_data(params)
25
+ params.transform_values { |v| v.class == Hash && v[:tempfile] ? v[:tempfile].read : v }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ # https://github.com/ota42y/openapi_parser/issues/75
2
+ module OpenAPIParser
3
+ class PathItemFinder
4
+ private
5
+
6
+ def find_path_and_params(http_method, request_path)
7
+ return [request_path, {}] if matches_directly?(request_path, http_method)
8
+
9
+ matching = matching_paths_with_params(request_path, http_method)
10
+
11
+ matching.min_by { |match| match[1].size }
12
+ end
13
+ end
14
+ end
@@ -4,7 +4,7 @@ module Fakeit
4
4
  def array_example(options)
5
5
  example_options = add_depth(options)
6
6
  if example_options[:use_static][type: 'array', property: example_options[:property]]
7
- generate_array_example(example_options, -> { min_array })
7
+ generate_array_example(example_options, -> { non_empty_size })
8
8
  else
9
9
  generate_array_example(example_options, -> { random_array_size(example_options) })
10
10
  end
@@ -18,17 +18,17 @@ module Fakeit
18
18
  end
19
19
 
20
20
  def random_array_size(example_options)
21
- uniqueItems ? min_array : Faker::Number.between(from: min_array, to: max_array(example_options[:depth]))
21
+ uniqueItems ? non_empty_size : Faker::Number.between(from: min_array, to: max_array(example_options[:depth]))
22
22
  end
23
23
 
24
24
  def generate_items(size, retries, example_options, result)
25
- loop do
25
+ while result.size < size
26
26
  item = items.to_example(example_options)
27
27
 
28
28
  if need_retry?(item, result, retries)
29
29
  retries -= 1
30
- elsif (result << item).size >= size
31
- break
30
+ else
31
+ result << item
32
32
  end
33
33
  end
34
34
  end
@@ -41,6 +41,10 @@ module Fakeit
41
41
  uniqueItems && result.include?(item) && retries.positive?
42
42
  end
43
43
 
44
+ def non_empty_size
45
+ [min_array, 1].max
46
+ end
47
+
44
48
  def min_array
45
49
  minItems || 1
46
50
  end
@@ -11,7 +11,8 @@ module Fakeit
11
11
  now = Time.now
12
12
  Time.new(now.year, now.month, now.day, 0, 0, 0, now.utc_offset).iso8601
13
13
  end,
14
- 'binary' => -> { '1111' }
14
+ 'binary' => -> { 'binary' },
15
+ 'byte' => -> { 'Ynl0ZQ==' }
15
16
  }.freeze
16
17
 
17
18
  RANDOM_FORMAT_HANDLERS = {
@@ -21,7 +22,8 @@ module Fakeit
21
22
  'email' => -> { Faker::Internet.email },
22
23
  'date' => -> { Faker::Date.backward(days: 100).iso8601 },
23
24
  'date-time' => -> { Faker::Time.backward(days: 100).iso8601 },
24
- 'binary' => -> { Faker::String.random(length: (4..100).step(4)) }
25
+ 'binary' => -> { Faker::String.random(length: 1..30) },
26
+ 'byte' => -> { Base64.strict_encode64(Faker::String.random(length: 1..30)) }
25
27
  }.freeze
26
28
 
27
29
  def string_example(example_options)
@@ -5,13 +5,10 @@ module Fakeit
5
5
  @operation = operation
6
6
  end
7
7
 
8
- def validate(body: '', params: {}, headers: {})
8
+ def validate(body: {}, params: {}, headers: {})
9
9
  options = OpenAPIParser::SchemaValidator::Options.new(coerce_value: true)
10
10
 
11
- if request_content_type
12
- body_data = parse(body)
13
- @operation.validate_request_body(request_content_type, body_data)
14
- end
11
+ validate_body(body) unless request_content_types.empty?
15
12
  @operation.validate_path_params(options)
16
13
  @operation.validate_request_parameter(params, headers, options)
17
14
  rescue StandardError => e
@@ -20,14 +17,21 @@ module Fakeit
20
17
 
21
18
  private
22
19
 
23
- def parse(body)
24
- JSON.parse(body)
25
- rescue StandardError
26
- raise ValidationError, 'Invalid json payload'
20
+ def validate_body(body)
21
+ if request_content_types.include?(body[:media_type])
22
+ @operation.validate_request_body(body[:media_type], body[:data]) if can_validate?(body[:media_type])
23
+ else
24
+ raise ValidationError, 'Invalid request content type' if body[:media_type]
25
+ raise ValidationError, 'Request body is required' if request_body.required
26
+ end
27
+ end
28
+
29
+ def can_validate?(media_type)
30
+ media_type =~ %r{^application/.*json} || media_type == 'multipart/form-data'
27
31
  end
28
32
 
29
- def request_content_type
30
- request_body&.content&.find { |k, _| k =~ %r{^application/.*json} }&.first
33
+ def request_content_types
34
+ request_body&.content&.keys.to_a
31
35
  end
32
36
 
33
37
  def request_body
@@ -1,3 +1,3 @@
1
1
  module Fakeit
2
- VERSION = '0.5.1'.freeze
2
+ VERSION = '0.6.2'.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.5.1
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Feng
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-03 00:00:00.000000000 Z
11
+ date: 2020-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -112,30 +112,30 @@ dependencies:
112
112
  name: faker
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: '2.2'
117
+ version: 2.13.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: '2.2'
124
+ version: 2.13.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: openapi_parser
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 0.8.0
131
+ version: 0.11.2
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 0.8.0
138
+ version: 0.11.2
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rack
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '4.6'
187
+ version: '4.8'
188
188
  type: :runtime
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: '4.6'
194
+ version: '4.8'
195
195
  description: Create mock server from Openapi specification
196
196
  email:
197
197
  - realfengjia@foxmail.com
@@ -215,8 +215,9 @@ files:
215
215
  - fakeit.gemspec
216
216
  - lib/fakeit.rb
217
217
  - lib/fakeit/app/app.rb
218
+ - lib/fakeit/app/body_parser.rb
218
219
  - lib/fakeit/app/options.rb
219
- - lib/fakeit/core_extensions/findable.rb
220
+ - lib/fakeit/core_extensions/path_item_finder.rb
220
221
  - lib/fakeit/core_extensions/schema.rb
221
222
  - lib/fakeit/logger.rb
222
223
  - lib/fakeit/middleware/recorder.rb
@@ -1,12 +0,0 @@
1
- module OpenAPIParser
2
- module Findable
3
- def purge_object_cache
4
- return if @purged
5
-
6
- @find_object_cache = {}
7
- @purged = true
8
-
9
- _openapi_all_child_objects.values.each(&:purge_object_cache)
10
- end
11
- end
12
- end