fakeit 0.5.1 → 0.6.2

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: 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