fakeit 0.6.3 → 0.9.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: 35c58ad2d52ce6f2ba2375738faaed686b7945ce0d3e438d0d5e3e78f7d32d71
4
- data.tar.gz: 4c9a1566b7256b2b5b8fb7772daf1329810644b646f2ac0c939d5a3fd824a8db
3
+ metadata.gz: dbb5973b840c21eddd94a398c62a312bbbf21dba4b06323ca4ab8bf2fd7318f4
4
+ data.tar.gz: 3a2d30ed95aa61b39f68c3ddce26815ee7156f5a620a2fea097bf2d3466d5be6
5
5
  SHA512:
6
- metadata.gz: 0c3b0375ac956484083b108bb3284ccd33adda44e002b310b7e44fdb2ce151f1b62729a095f9caa02d2953d7dd809e4144fa33612756aa3189cee358e279ae18
7
- data.tar.gz: 71e3391f4570e12b3c940476e0657e700088ef72f122ccf6e354e71e43ed47ef3d082e7d7f972fc5b35c3fb111aba38110b00d36725eaaafbaeb18750d6ebc96
6
+ metadata.gz: 35fe9c896913f0a946586ad4945960b01e3b665c1eb101d7265ec67bb1b3e59e91e224b72ef2d330455f770e6546d97d172f7d63a2849a16e3a94053196fbad0
7
+ data.tar.gz: a0425724e4c9fb66f2feda3adc505c752b9b001ac8db6aee75715a20a06478434696bf4b082887b9c8e34470d029fdc7e88d236e32837307aa9ac0339dca34fe
data/.circleci/config.yml CHANGED
@@ -12,7 +12,7 @@ jobs:
12
12
 
13
13
  docker:
14
14
  # specify the version you desire here
15
- - image: circleci/ruby:2.7.0
15
+ - image: circleci/ruby:3.0.0
16
16
 
17
17
  # Specify service dependencies here if necessary
18
18
  # CircleCI maintains a library of pre-built images
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7
2
+ TargetRubyVersion: 3.0
3
3
  NewCops: enable
4
4
 
5
5
  Style/Documentation:
data/CHANGELOG.md ADDED
@@ -0,0 +1,176 @@
1
+ # Changelog
2
+
3
+ ## [v0.8.0](https://github.com/JustinFeng/fakeit/tree/v0.8.0) (2021-02-27)
4
+
5
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.7.1...v0.8.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Upgraded to ruby 3.0.0
10
+
11
+ ## [v0.7.1](https://github.com/JustinFeng/fakeit/tree/v0.7.1) (2021-02-07)
12
+
13
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.7.0...v0.7.1)
14
+
15
+ **Fixed bugs:**
16
+
17
+ - ERROR NoMethodError: undefined method `to\_example' for \# [\#20](https://github.com/JustinFeng/fakeit/issues/20)
18
+
19
+ ## [v0.7.0](https://github.com/JustinFeng/fakeit/tree/v0.7.0) (2020-10-22)
20
+
21
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.6.3...v0.7.0)
22
+
23
+ **Implemented enhancements:**
24
+
25
+ - Supported change mock server behaviour on the fly
26
+ - Allowed to redirect console log to a file
27
+
28
+ ## [v0.6.3](https://github.com/JustinFeng/fakeit/tree/v0.6.3) (2020-09-11)
29
+
30
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.6.2...v0.6.3)
31
+
32
+ **Implemented enhancements:**
33
+
34
+ - Enhanced regex example generation
35
+
36
+ ## [v0.6.2](https://github.com/JustinFeng/fakeit/tree/v0.6.2) (2020-07-12)
37
+
38
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.6.1...v0.6.2)
39
+
40
+ ## [v0.6.1](https://github.com/JustinFeng/fakeit/tree/v0.6.1) (2020-05-02)
41
+
42
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.6.0...v0.6.1)
43
+
44
+ ## [v0.6.0](https://github.com/JustinFeng/fakeit/tree/v0.6.0) (2020-05-02)
45
+
46
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.5.3...v0.6.0)
47
+
48
+ **Implemented enhancements:**
49
+
50
+ - Added support for multipart/form-data validation
51
+
52
+ **Fixed bugs:**
53
+
54
+ - Multipart request contain special character will respond 500 [\#16](https://github.com/JustinFeng/fakeit/issues/16)
55
+
56
+ ## [v0.5.3](https://github.com/JustinFeng/fakeit/tree/v0.5.3) (2020-04-05)
57
+
58
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.5.2...v0.5.3)
59
+
60
+ ## [v0.5.2](https://github.com/JustinFeng/fakeit/tree/v0.5.2) (2020-04-03)
61
+
62
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.5.1...v0.5.2)
63
+
64
+ ## [v0.5.1](https://github.com/JustinFeng/fakeit/tree/v0.5.1) (2020-04-03)
65
+
66
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.5.0...v0.5.1)
67
+
68
+ ## [v0.5.0](https://github.com/JustinFeng/fakeit/tree/v0.5.0) (2020-04-03)
69
+
70
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.4.2...v0.5.0)
71
+
72
+ **Merged pull requests:**
73
+
74
+ - Bump rack from 2.0.7 to 2.0.8 [\#18](https://github.com/JustinFeng/fakeit/pull/18) ([dependabot[bot]](https://github.com/apps/dependabot))
75
+
76
+ ## [v0.4.2](https://github.com/JustinFeng/fakeit/tree/v0.4.2) (2019-11-22)
77
+
78
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.4.1...v0.4.2)
79
+
80
+ ## [v0.4.1](https://github.com/JustinFeng/fakeit/tree/v0.4.1) (2019-11-21)
81
+
82
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.4.0...v0.4.1)
83
+
84
+ **Merged pull requests:**
85
+
86
+ - Bump rack-cors from 1.0.3 to 1.0.6 [\#17](https://github.com/JustinFeng/fakeit/pull/17) ([dependabot[bot]](https://github.com/apps/dependabot))
87
+
88
+ ## [v0.4.0](https://github.com/JustinFeng/fakeit/tree/v0.4.0) (2019-10-09)
89
+
90
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.3.1...v0.4.0)
91
+
92
+ **Implemented enhancements:**
93
+
94
+ - Implement support for watching for changes in spec/yaml file. [\#15](https://github.com/JustinFeng/fakeit/issues/15)
95
+
96
+ ## [v0.3.1](https://github.com/JustinFeng/fakeit/tree/v0.3.1) (2019-09-01)
97
+
98
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.3.0...v0.3.1)
99
+
100
+ ## [v0.3.0](https://github.com/JustinFeng/fakeit/tree/v0.3.0) (2019-08-27)
101
+
102
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.2.1...v0.3.0)
103
+
104
+ **Closed issues:**
105
+
106
+ - Missing "motivation" section in readme [\#14](https://github.com/JustinFeng/fakeit/issues/14)
107
+
108
+ ## [v0.2.1](https://github.com/JustinFeng/fakeit/tree/v0.2.1) (2019-08-04)
109
+
110
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.2.0...v0.2.1)
111
+
112
+ **Implemented enhancements:**
113
+
114
+ - Support .yaml files [\#9](https://github.com/JustinFeng/fakeit/issues/9)
115
+
116
+ **Fixed bugs:**
117
+
118
+ - Adjust integer generation bounds [\#12](https://github.com/JustinFeng/fakeit/issues/12)
119
+
120
+ **Closed issues:**
121
+
122
+ - End to End Tests [\#8](https://github.com/JustinFeng/fakeit/issues/8)
123
+
124
+ **Merged pull requests:**
125
+
126
+ - support .yaml files [\#10](https://github.com/JustinFeng/fakeit/pull/10) ([monsterkrampe](https://github.com/monsterkrampe))
127
+
128
+ ## [v0.2.0](https://github.com/JustinFeng/fakeit/tree/v0.2.0) (2019-07-17)
129
+
130
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.1.5...v0.2.0)
131
+
132
+ **Implemented enhancements:**
133
+
134
+ - Generate more array elements with performance considered [\#7](https://github.com/JustinFeng/fakeit/issues/7)
135
+ - Non random response [\#5](https://github.com/JustinFeng/fakeit/issues/5)
136
+
137
+ **Fixed bugs:**
138
+
139
+ - Invalid example for number type with more than 2 decimal places 'multipleOf' [\#6](https://github.com/JustinFeng/fakeit/issues/6)
140
+
141
+ ## [v0.1.5](https://github.com/JustinFeng/fakeit/tree/v0.1.5) (2019-06-28)
142
+
143
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.1.4...v0.1.5)
144
+
145
+ **Implemented enhancements:**
146
+
147
+ - Allow CORS [\#4](https://github.com/JustinFeng/fakeit/pull/4) ([monsterkrampe](https://github.com/monsterkrampe))
148
+
149
+ ## [v0.1.4](https://github.com/JustinFeng/fakeit/tree/v0.1.4) (2019-06-25)
150
+
151
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.1.3...v0.1.4)
152
+
153
+ **Implemented enhancements:**
154
+
155
+ - W, \[2019-06-25T03:00:29.635993 \#1\] WARN -- : Unknown string format: guid [\#2](https://github.com/JustinFeng/fakeit/issues/2)
156
+
157
+ **Fixed bugs:**
158
+
159
+ - Request not completing [\#3](https://github.com/JustinFeng/fakeit/issues/3)
160
+ - Stack level too deep in docker container [\#1](https://github.com/JustinFeng/fakeit/issues/1)
161
+
162
+ ## [v0.1.3](https://github.com/JustinFeng/fakeit/tree/v0.1.3) (2019-06-16)
163
+
164
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.1.2...v0.1.3)
165
+
166
+ ## [v0.1.2](https://github.com/JustinFeng/fakeit/tree/v0.1.2) (2019-06-05)
167
+
168
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/v0.1.1...v0.1.2)
169
+
170
+ ## [v0.1.1](https://github.com/JustinFeng/fakeit/tree/v0.1.1) (2019-05-26)
171
+
172
+ [Full Changelog](https://github.com/JustinFeng/fakeit/compare/4f94874eaf87300496e9de632cd659a031cb3ce2...v0.1.1)
173
+
174
+
175
+
176
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fakeit (0.6.3)
4
+ fakeit (0.9.0)
5
5
  faker (= 2.13.0)
6
6
  openapi_parser (= 0.12.1)
7
7
  rack (~> 2.0)
@@ -9,22 +9,23 @@ PATH
9
9
  rainbow (~> 3.0)
10
10
  regexp-examples (= 1.5.1)
11
11
  slop (~> 4.8)
12
+ webrick (~> 1.7)
12
13
 
13
14
  GEM
14
15
  remote: https://rubygems.org/
15
16
  specs:
16
- ast (2.4.1)
17
+ ast (2.4.2)
17
18
  byebug (11.1.3)
18
- concurrent-ruby (1.1.7)
19
+ concurrent-ruby (1.1.8)
19
20
  diff-lcs (1.4.4)
20
- docile (1.3.2)
21
+ docile (1.3.5)
21
22
  faker (2.13.0)
22
23
  i18n (>= 1.6, < 2)
23
- i18n (1.8.5)
24
+ i18n (1.8.9)
24
25
  concurrent-ruby (~> 1.0)
25
26
  openapi_parser (0.12.1)
26
- parallel (1.19.2)
27
- parser (2.7.1.4)
27
+ parallel (1.20.1)
28
+ parser (3.0.0.0)
28
29
  ast (~> 2.4.1)
29
30
  rack (2.2.3)
30
31
  rack-cors (1.1.1)
@@ -32,41 +33,46 @@ GEM
32
33
  rack-test (1.1.0)
33
34
  rack (>= 1.0, < 3)
34
35
  rainbow (3.0.0)
35
- rake (12.3.3)
36
+ rake (13.0.3)
36
37
  regexp-examples (1.5.1)
37
- regexp_parser (1.7.1)
38
+ regexp_parser (2.1.1)
38
39
  rexml (3.2.4)
39
- rspec (3.9.0)
40
- rspec-core (~> 3.9.0)
41
- rspec-expectations (~> 3.9.0)
42
- rspec-mocks (~> 3.9.0)
43
- rspec-core (3.9.2)
44
- rspec-support (~> 3.9.3)
45
- rspec-expectations (3.9.2)
40
+ rspec (3.10.0)
41
+ rspec-core (~> 3.10.0)
42
+ rspec-expectations (~> 3.10.0)
43
+ rspec-mocks (~> 3.10.0)
44
+ rspec-core (3.10.1)
45
+ rspec-support (~> 3.10.0)
46
+ rspec-expectations (3.10.1)
46
47
  diff-lcs (>= 1.2.0, < 2.0)
47
- rspec-support (~> 3.9.0)
48
- rspec-mocks (3.9.1)
48
+ rspec-support (~> 3.10.0)
49
+ rspec-mocks (3.10.2)
49
50
  diff-lcs (>= 1.2.0, < 2.0)
50
- rspec-support (~> 3.9.0)
51
- rspec-support (3.9.3)
52
- rubocop (0.90.0)
51
+ rspec-support (~> 3.10.0)
52
+ rspec-support (3.10.2)
53
+ rubocop (1.10.0)
53
54
  parallel (~> 1.10)
54
- parser (>= 2.7.1.1)
55
+ parser (>= 3.0.0.0)
55
56
  rainbow (>= 2.2.2, < 4.0)
56
- regexp_parser (>= 1.7)
57
+ regexp_parser (>= 1.8, < 3.0)
57
58
  rexml
58
- rubocop-ast (>= 0.3.0, < 1.0)
59
+ rubocop-ast (>= 1.2.0, < 2.0)
59
60
  ruby-progressbar (~> 1.7)
60
- unicode-display_width (>= 1.4.0, < 2.0)
61
- rubocop-ast (0.3.0)
62
- parser (>= 2.7.1.4)
63
- ruby-progressbar (1.10.1)
64
- simplecov (0.19.0)
61
+ unicode-display_width (>= 1.4.0, < 3.0)
62
+ rubocop-ast (1.4.1)
63
+ parser (>= 2.7.1.5)
64
+ rubocop-rake (0.5.1)
65
+ rubocop
66
+ ruby-progressbar (1.11.0)
67
+ simplecov (0.21.2)
65
68
  docile (~> 1.1)
66
69
  simplecov-html (~> 0.11)
67
- simplecov-html (0.12.2)
70
+ simplecov_json_formatter (~> 0.1)
71
+ simplecov-html (0.12.3)
72
+ simplecov_json_formatter (0.1.2)
68
73
  slop (4.8.2)
69
- unicode-display_width (1.7.0)
74
+ unicode-display_width (2.0.0)
75
+ webrick (1.7.0)
70
76
 
71
77
  PLATFORMS
72
78
  ruby
@@ -76,10 +82,11 @@ DEPENDENCIES
76
82
  byebug (~> 11.0)
77
83
  fakeit!
78
84
  rack-test (~> 1.1)
79
- rake (~> 12.0)
85
+ rake (~> 13.0)
80
86
  rspec (~> 3.0)
81
- rubocop (~> 0.80)
87
+ rubocop (~> 1.10)
88
+ rubocop-rake (~> 0.5)
82
89
  simplecov (~> 0.18)
83
90
 
84
91
  BUNDLED WITH
85
- 2.1.2
92
+ 2.2.11
data/README.md CHANGED
@@ -35,6 +35,7 @@ After tried several existing options, we cannot find a best solution to meet all
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
+ * [Experimental] Support plain text and binary response, e.g. `application/pdf`
38
39
 
39
40
  ## Installation
40
41
 
@@ -48,13 +49,14 @@ Or use the [docker image](https://hub.docker.com/r/realfengjia/fakeit)
48
49
 
49
50
  $ fakeit --spec <Local file or remote url>
50
51
 
51
- Command line options:
52
+ ### Command line options
52
53
 
53
54
  $ fakeit --help
54
55
  usage:
55
56
  --spec spec file uri (required)
56
57
  -p, --port custom port
57
58
  -q, --quiet mute request and response log
59
+ -l, --log-file redirect log to a file
58
60
  --permissive log validation error as warning instead of denying request
59
61
  --use-example use example provided in spec if exists
60
62
  --static generate static response
@@ -71,6 +73,33 @@ Command line options:
71
73
  * Regarding `--use-example` mode, property without example specified will still be randomly or statically generated
72
74
  * Random response generation can not handle recursive schema reference. If you do need it in your spec file, please provide `example` property for the recursive part of schema and specify `--use-example` option.
73
75
 
76
+ ### Configuration endpoint
77
+
78
+ Mock server behaviour can be changed on the fly
79
+
80
+ Retrieve current config:
81
+
82
+ GET /__fakeit_config__
83
+
84
+ Update config:
85
+
86
+ PUT /__fakeit_config__
87
+
88
+ Request and response:
89
+ ```json
90
+ {
91
+ "permissive": false,
92
+ "use_example": true,
93
+ "static": false,
94
+ "static_types": [
95
+ "integer"
96
+ ],
97
+ "static_properties": [
98
+ "id"
99
+ ]
100
+ }
101
+ ```
102
+
74
103
  ## Development
75
104
 
76
105
  After checking out the repo, run `bundle install` to install dependencies. Then, run `rake` to run the tests.
data/bin/fakeit CHANGED
@@ -10,6 +10,7 @@ begin
10
10
  o.string '--spec', 'spec file uri (required)', required: true
11
11
  o.integer '-p', '--port', 'custom port'
12
12
  o.bool '-q', '--quiet', 'mute request and response log'
13
+ o.string '-l', '--log-file', 'redirect log to a file'
13
14
  o.bool '--permissive', 'log validation error as warning instead of denying request'
14
15
  o.bool '--use-example', 'use example provided in spec if exists'
15
16
  o.bool '--static', 'generate static response'
@@ -53,6 +54,9 @@ options = Fakeit::App::Options.new(
53
54
  )
54
55
  app = Fakeit.build(opts[:spec], options)
55
56
 
57
+ $stderr.reopen(File.new(opts[:log_file], File::WRONLY | File::TRUNC | File::CREAT)) if opts[:log_file]
58
+ $stderr.sync = true
59
+
56
60
  app.use Rack::Cors do
57
61
  allow do
58
62
  origins '*'
data/fakeit.gemspec CHANGED
@@ -22,14 +22,15 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = 'fakeit'
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.required_ruby_version = '>= 2.7.0'
25
+ spec.required_ruby_version = '>= 3.0.0'
26
26
 
27
27
  spec.add_development_dependency 'bundler', '~> 2.0'
28
28
  spec.add_development_dependency 'byebug', '~> 11.0'
29
29
  spec.add_development_dependency 'rack-test', '~> 1.1'
30
- spec.add_development_dependency 'rake', '~> 12.0'
30
+ spec.add_development_dependency 'rake', '~> 13.0'
31
31
  spec.add_development_dependency 'rspec', '~> 3.0'
32
- spec.add_development_dependency 'rubocop', '~> 0.80'
32
+ spec.add_development_dependency 'rubocop', '~> 1.10'
33
+ spec.add_development_dependency 'rubocop-rake', '~> 0.5'
33
34
  spec.add_development_dependency 'simplecov', '~> 0.18'
34
35
 
35
36
  spec.add_dependency 'faker', '2.13.0'
@@ -39,4 +40,5 @@ Gem::Specification.new do |spec|
39
40
  spec.add_dependency 'rainbow', '~> 3.0'
40
41
  spec.add_dependency 'regexp-examples', '1.5.1'
41
42
  spec.add_dependency 'slop', '~> 4.8'
43
+ spec.add_dependency 'webrick', '~> 1.7'
42
44
  end
data/lib/fakeit.rb CHANGED
@@ -9,13 +9,13 @@ require 'rack'
9
9
  require 'logger'
10
10
  require 'rainbow'
11
11
 
12
- Dir.glob(File.join(File.dirname(__FILE__), 'fakeit', '**/*.rb')).sort.each { require _1 }
12
+ Dir.glob(File.join(File.dirname(__FILE__), 'fakeit', '**/*.rb')).each { require _1 }
13
13
 
14
14
  module Fakeit
15
15
  class << self
16
16
  def build(spec_file, options)
17
17
  Rack::Builder.new do
18
- run App.create(spec_file, options)
18
+ run App::AppBuilder.new(spec_file, options).build
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,23 @@
1
+ module Fakeit
2
+ module App
3
+ class AppBuilder
4
+ def initialize(spec_file, options)
5
+ @config_route = Routes::ConfigRoute.new(options)
6
+ @openapi_route = Routes::OpenapiRoute.new(spec_file)
7
+ end
8
+
9
+ def build
10
+ proc do |env|
11
+ request = Rack::Request.new(env)
12
+
13
+ case request.path_info
14
+ when '/__fakeit_config__'
15
+ @config_route.call(request)
16
+ else
17
+ @openapi_route.call(request, @config_route.options)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ module Fakeit
2
+ module App
3
+ module Helpers
4
+ class BodyParser
5
+ class << self
6
+ def parse(request)
7
+ case request.media_type
8
+ when %r{^application/.*json}
9
+ { media_type: request.media_type, data: parse_json(request.body.read) }
10
+ when 'multipart/form-data'
11
+ { media_type: request.media_type, data: parse_form_data(request.params) }
12
+ else
13
+ { media_type: request.media_type, data: request.body.read }
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def parse_json(body)
20
+ body.empty? ? {} : JSON.parse(body)
21
+ rescue StandardError
22
+ raise Fakeit::Validation::ValidationError, 'Invalid json payload'
23
+ end
24
+
25
+ def parse_form_data(params)
26
+ params.transform_values { |v| v.instance_of?(Hash) && v[:tempfile] ? v[:tempfile].read : v }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,19 @@
1
+ module Fakeit
2
+ module App
3
+ module Helpers
4
+ class ResponseBuilder
5
+ class << self
6
+ def error(code, err) = [code, { 'Content-Type' => 'application/json' }, [{ message: err.message }.to_json]]
7
+
8
+ def not_found = [404, {}, ['Not Found']]
9
+
10
+ def method_not_allowed = [405, {}, ['Method Not Allowed']]
11
+
12
+ def unsupported_media_type = [415, {}, ['Unsupported Media Type']]
13
+
14
+ def ok(body) = [200, { 'Content-Type' => 'application/json' }, [body.to_json]]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -14,6 +14,16 @@ module Fakeit
14
14
  def use_static?(type: nil, property: nil)
15
15
  @static || @static_types.include?(type) || @static_properties.include?(property)
16
16
  end
17
+
18
+ def to_hash
19
+ {
20
+ permissive: @permissive,
21
+ use_example: @use_example,
22
+ static: @static,
23
+ static_types: @static_types,
24
+ static_properties: @static_properties
25
+ }
26
+ end
17
27
  end
18
28
  end
19
29
  end
@@ -0,0 +1,36 @@
1
+ module Fakeit
2
+ module App
3
+ module Routes
4
+ class ConfigRoute
5
+ attr_reader :options
6
+
7
+ def initialize(options) = @options = options
8
+
9
+ def call(request)
10
+ case [request.request_method, request.media_type]
11
+ in ['GET', _]
12
+ Fakeit::App::Helpers::ResponseBuilder.ok(@options.to_hash)
13
+ in ['PUT', 'application/json']
14
+ update(request)
15
+ in ['PUT', _]
16
+ Fakeit::App::Helpers::ResponseBuilder.unsupported_media_type
17
+ else
18
+ Fakeit::App::Helpers::ResponseBuilder.method_not_allowed
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def update(request)
25
+ body = Fakeit::App::Helpers::BodyParser.parse(request)[:data]
26
+ @options = Fakeit::App::Options.new(**body.transform_keys(&:to_sym))
27
+
28
+ Fakeit::App::Helpers::ResponseBuilder.ok(@options.to_hash)
29
+ rescue ArgumentError => e
30
+ Logger.warn(Rainbow(e.message).red)
31
+ Fakeit::App::Helpers::ResponseBuilder.error(422, e)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ module Fakeit
2
+ module App
3
+ module Routes
4
+ class OpenapiRoute
5
+ def initialize(spec_file) = @specification = Fakeit::Openapi::Specification.new(spec_file)
6
+
7
+ def call(request, options)
8
+ @specification
9
+ .operation(request.request_method.downcase.to_sym, request.path_info, options)
10
+ .then { _1 ? handle(_1, request, options) : Fakeit::App::Helpers::ResponseBuilder.not_found }
11
+ end
12
+
13
+ private
14
+
15
+ def handle(operation, request, options)
16
+ validate(operation, request)
17
+ response(operation)
18
+ rescue Fakeit::Validation::ValidationError => e
19
+ Logger.warn(Rainbow(e.message).red)
20
+ options.permissive ? response(operation) : Fakeit::App::Helpers::ResponseBuilder.error(418, e)
21
+ end
22
+
23
+ def response(operation) = [operation.status, operation.headers, [operation.body]]
24
+
25
+ def validate(operation, request)
26
+ operation.validate(
27
+ body: Helpers::BodyParser.parse(request),
28
+ params: parse_query(request.query_string),
29
+ headers: headers(request)
30
+ )
31
+ end
32
+
33
+ def headers(request)
34
+ request
35
+ .each_header
36
+ .select { |k, _| k.start_with? 'HTTP_' }
37
+ .map { |k, v| [k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-'), v] }
38
+ .to_h
39
+ end
40
+
41
+ def parse_query(query_string)
42
+ rack_query = Rack::Utils.parse_nested_query(query_string)
43
+ cgi_query = CGI.parse(query_string)
44
+
45
+ rack_query.merge(cgi_query.slice(*rack_query.keys)) do |_, oldval, newval|
46
+ newval.is_a?(Array) && newval.size > 1 ? newval : oldval
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ require 'fakeit/openapi/schema'
2
+
3
+ module OpenAPIParser
4
+ module Schemas
5
+ class Reference
6
+ def to_example(_) = raise(Fakeit::Openapi::ReferenceError, "Invalid $ref at \"#{ref}\"")
7
+ end
8
+ end
9
+ end
@@ -7,9 +7,7 @@ module OpenAPIParser
7
7
 
8
8
  alias old_type type
9
9
 
10
- def type
11
- old_type || inferred_type
12
- end
10
+ def type = old_type || inferred_type
13
11
 
14
12
  private
15
13
 
data/lib/fakeit/logger.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  module Fakeit
2
- $stdout.sync = true
3
- Logger = ::Logger.new($stdout)
2
+ Logger = ::Logger.new($stderr)
4
3
  end
@@ -1,9 +1,7 @@
1
1
  module Fakeit
2
2
  module Middleware
3
3
  class Recorder
4
- def initialize(app)
5
- @app = app
6
- end
4
+ def initialize(app) = @app = app
7
5
 
8
6
  def call(env)
9
7
  env
@@ -20,9 +18,7 @@ module Fakeit
20
18
  &.tap { |body| body.rewind }
21
19
  end
22
20
 
23
- def log_response(response)
24
- Logger.info("Response body: #{response[2].first}")
25
- end
21
+ def log_response(response) = Logger.info("Response body: #{response[2].first}")
26
22
  end
27
23
  end
28
24
  end
@@ -33,25 +33,15 @@ module Fakeit
33
33
  end
34
34
  end
35
35
 
36
- def add_depth(example_options)
37
- { **example_options, depth: example_options[:depth] + 1 }
38
- end
36
+ def add_depth(example_options) = { **example_options, depth: example_options[:depth] + 1 }
39
37
 
40
- def need_retry?(item, result, retries)
41
- uniqueItems && result.include?(item) && retries.positive?
42
- end
38
+ def need_retry?(item, result, retries) = uniqueItems && result.include?(item) && retries.positive?
43
39
 
44
- def non_empty_size
45
- [min_array, 1].max
46
- end
40
+ def non_empty_size = [min_array, 1].max
47
41
 
48
- def min_array
49
- minItems || 1
50
- end
42
+ def min_array = minItems || 1
51
43
 
52
- def max_array(depth)
53
- maxItems || min_array + (depth > 1 ? 2 : 9)
54
- end
44
+ def max_array(depth) = maxItems || min_array + (depth > 1 ? 2 : 9)
55
45
  end
56
46
  end
57
47
  end
@@ -29,21 +29,13 @@ module Fakeit
29
29
  end
30
30
  end
31
31
 
32
- def int_rand_begin
33
- min_int / int_multiple + int_rand_begin_adjust
34
- end
32
+ def int_rand_begin = min_int / int_multiple + int_rand_begin_adjust
35
33
 
36
- def int_rand_end
37
- max_int / int_multiple
38
- end
34
+ def int_rand_end = max_int / int_multiple
39
35
 
40
- def int_rand_begin_adjust
41
- (min_int % int_multiple).zero? ? 0 : 1
42
- end
36
+ def int_rand_begin_adjust = (min_int % int_multiple).zero? ? 0 : 1
43
37
 
44
- def int_multiple
45
- multipleOf || 1
46
- end
38
+ def int_multiple = multipleOf || 1
47
39
 
48
40
  def min_int
49
41
  if minimum
@@ -14,35 +14,22 @@ module Fakeit
14
14
 
15
15
  private
16
16
 
17
- def static_number_example
18
- (num_rand_end * num_multiple)
19
- .then { multipleOf ? _1 : _1.round(2) }
20
- end
17
+ def static_number_example = (num_rand_end * num_multiple).then { multipleOf ? _1 : _1.round(2) }
21
18
 
22
19
  def random_number_example
23
20
  (Faker::Number.between(from: num_rand_begin, to: num_rand_end) * num_multiple)
24
21
  .then { multipleOf ? _1 : _1.round(2) }
25
22
  end
26
23
 
27
- def num_rand_begin
28
- multipleOf ? (min_num / multipleOf).ceil : min_num
29
- end
24
+ def num_rand_begin = multipleOf ? (min_num / multipleOf).ceil : min_num
30
25
 
31
- def num_rand_end
32
- multipleOf ? (max_num / multipleOf).floor : max_num
33
- end
26
+ def num_rand_end = multipleOf ? (max_num / multipleOf).floor : max_num
34
27
 
35
- def num_multiple
36
- multipleOf || 1
37
- end
28
+ def num_multiple = multipleOf || 1
38
29
 
39
- def min_num
40
- (minimum || MIN_NUM).to_f.ceil(2)
41
- end
30
+ def min_num = (minimum || MIN_NUM).to_f.ceil(2)
42
31
 
43
- def max_num
44
- (maximum || MAX_NUM).to_f.floor(2)
45
- end
32
+ def max_num = (maximum || MAX_NUM).to_f.floor(2)
46
33
  end
47
34
  end
48
35
  end
@@ -65,13 +65,9 @@ module Fakeit
65
65
  end
66
66
  end
67
67
 
68
- def static_string_with_length
69
- '1' * max_string_length
70
- end
68
+ def static_string_with_length = '1' * max_string_length
71
69
 
72
- def static_string_format
73
- (STATIC_FORMAT_HANDLERS[format] || method(:unknown_format))[]
74
- end
70
+ def static_string_format = (STATIC_FORMAT_HANDLERS[format] || method(:unknown_format))[]
75
71
 
76
72
  def static_string_pattern
77
73
  @static_string_pattern ||= @string_pattern.examples(
@@ -79,32 +75,20 @@ module Fakeit
79
75
  ).first
80
76
  end
81
77
 
82
- def length_constraint
83
- minLength || maxLength
84
- end
78
+ def length_constraint = minLength || maxLength
85
79
 
86
- def string_with_length
87
- Faker::Internet.username(specifier: min_string_length..max_string_length)
88
- end
80
+ def string_with_length = Faker::Internet.username(specifier: min_string_length..max_string_length)
89
81
 
90
- def min_string_length
91
- minLength || 0
92
- end
82
+ def min_string_length = minLength || 0
93
83
 
94
- def max_string_length
95
- maxLength || min_string_length + 10
96
- end
84
+ def max_string_length = maxLength || min_string_length + 10
97
85
 
98
- def random_string_format
99
- (RANDOM_FORMAT_HANDLERS[format] || method(:unknown_format))[]
100
- end
86
+ def random_string_format = (RANDOM_FORMAT_HANDLERS[format] || method(:unknown_format))[]
101
87
 
102
- def random_string_pattern
103
- @random_string_pattern ||= @string_pattern.random_example(max_repeater_variance: 1)
104
- end
88
+ def random_string_pattern = @random_string_pattern ||= @string_pattern.random_example(max_repeater_variance: 1)
105
89
 
106
90
  def unknown_format
107
- Fakeit::Logger.info("Unknown string format: #{format}")
91
+ Logger.info("Unknown string format: #{format}")
108
92
  'Unknown string format'
109
93
  end
110
94
  end
@@ -4,7 +4,8 @@ module Fakeit
4
4
  def load(src)
5
5
  parse_method = parse_method(src)
6
6
 
7
- open(src, &:read)
7
+ URI
8
+ .open(src, &:read)
8
9
  .then(&parse_method)
9
10
  .then(&OpenAPIParser.method(:parse))
10
11
  end
@@ -7,9 +7,7 @@ module Fakeit
7
7
  @app_options = app_options
8
8
  end
9
9
 
10
- def status
11
- response.first.to_i
12
- end
10
+ def status = response.first.to_i
13
11
 
14
12
  def headers
15
13
  response_headers
@@ -22,39 +20,31 @@ module Fakeit
22
20
  response_schema
23
21
  &.schema
24
22
  &.to_example(example_options)
25
- &.then(&JSON.method(:generate))
23
+ &.then(&method(:serialise))
26
24
  .to_s
27
25
  end
28
26
 
29
- def validate(**request_parts)
30
- @validator.validate(**request_parts)
31
- end
27
+ def validate(...) = @validator.validate(...)
32
28
 
33
29
  private
34
30
 
31
+ def serialise(body) = body.is_a?(String) ? body : JSON.generate(body)
32
+
35
33
  def example_options
36
34
  { use_example: @app_options.use_example, use_static: @app_options.method(:use_static?), depth: 0 }
37
35
  end
38
36
 
39
37
  def response_content
40
- response.last.content&.find { |k, _| k =~ %r{^application/.*json} }
38
+ response.last.content&.find { |k, _| k =~ %r{^application/.*json} || k == 'application/pdf' }
41
39
  end
42
40
 
43
- def response_schema
44
- response_content&.last
45
- end
41
+ def response_schema = response_content&.last
46
42
 
47
- def response_content_type
48
- response_content&.first
49
- end
43
+ def response_content_type = response_content&.first
50
44
 
51
- def response_headers
52
- response.last.headers
53
- end
45
+ def response_headers = response.last.headers
54
46
 
55
- def response
56
- @request_operation.operation_object.responses.response.min
57
- end
47
+ def response = @request_operation.operation_object.responses.response.min
58
48
  end
59
49
  end
60
50
  end
@@ -0,0 +1,6 @@
1
+ module Fakeit
2
+ module Openapi
3
+ class ReferenceError < StandardError
4
+ end
5
+ end
6
+ end
@@ -25,7 +25,7 @@ module Fakeit
25
25
  @mtime = new_mtime
26
26
  @doc = Fakeit::Openapi.load(@spec_file)
27
27
  rescue StandardError => _e
28
- Fakeit::Logger.warn(Rainbow('Invalid spec file, use previous snapshot instead').red)
28
+ Logger.warn(Rainbow('Invalid spec file, use previous snapshot instead').red)
29
29
  end
30
30
  end
31
31
  end
@@ -1,9 +1,7 @@
1
1
  module Fakeit
2
2
  module Validation
3
3
  class Validator
4
- def initialize(operation)
5
- @operation = operation
6
- end
4
+ def initialize(operation) = @operation = operation
7
5
 
8
6
  def validate(body: {}, params: {}, headers: {})
9
7
  options = OpenAPIParser::SchemaValidator::Options.new(coerce_value: true)
@@ -26,17 +24,11 @@ module Fakeit
26
24
  end
27
25
  end
28
26
 
29
- def can_validate?(media_type)
30
- media_type =~ %r{^application/.*json} || media_type == 'multipart/form-data'
31
- end
27
+ def can_validate?(media_type) = media_type =~ %r{^application/.*json} || media_type == 'multipart/form-data'
32
28
 
33
- def request_content_types
34
- request_body&.content&.keys.to_a
35
- end
29
+ def request_content_types = request_body&.content&.keys.to_a
36
30
 
37
- def request_body
38
- @operation.operation_object.request_body
39
- end
31
+ def request_body = @operation.operation_object.request_body
40
32
  end
41
33
  end
42
34
  end
@@ -1,3 +1,3 @@
1
1
  module Fakeit
2
- VERSION = '0.6.3'.freeze
2
+ VERSION = '0.9.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.6.3
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Feng
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-11 00:00:00.000000000 Z
11
+ date: 2021-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '12.0'
61
+ version: '13.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '12.0'
68
+ version: '13.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,28 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.80'
89
+ version: '1.10'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.80'
96
+ version: '1.10'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.5'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.5'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: simplecov
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -206,6 +220,20 @@ dependencies:
206
220
  - - "~>"
207
221
  - !ruby/object:Gem::Version
208
222
  version: '4.8'
223
+ - !ruby/object:Gem::Dependency
224
+ name: webrick
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '1.7'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '1.7'
209
237
  description: Create mock server from Openapi specification
210
238
  email:
211
239
  - realfengjia@foxmail.com
@@ -218,6 +246,7 @@ files:
218
246
  - ".gitignore"
219
247
  - ".rspec"
220
248
  - ".rubocop.yml"
249
+ - CHANGELOG.md
221
250
  - Gemfile
222
251
  - Gemfile.lock
223
252
  - LICENSE.txt
@@ -228,9 +257,13 @@ files:
228
257
  - docs/static.md
229
258
  - fakeit.gemspec
230
259
  - lib/fakeit.rb
231
- - lib/fakeit/app/app.rb
232
- - lib/fakeit/app/body_parser.rb
260
+ - lib/fakeit/app/app_builder.rb
261
+ - lib/fakeit/app/helpers/body_parser.rb
262
+ - lib/fakeit/app/helpers/response_builder.rb
233
263
  - lib/fakeit/app/options.rb
264
+ - lib/fakeit/app/routes/config_route.rb
265
+ - lib/fakeit/app/routes/openapi_route.rb
266
+ - lib/fakeit/core_extensions/reference.rb
234
267
  - lib/fakeit/core_extensions/schema.rb
235
268
  - lib/fakeit/logger.rb
236
269
  - lib/fakeit/middleware/recorder.rb
@@ -242,6 +275,7 @@ files:
242
275
  - lib/fakeit/openapi/example/string_example.rb
243
276
  - lib/fakeit/openapi/loader.rb
244
277
  - lib/fakeit/openapi/operation.rb
278
+ - lib/fakeit/openapi/reference_error.rb
245
279
  - lib/fakeit/openapi/schema.rb
246
280
  - lib/fakeit/openapi/specification.rb
247
281
  - lib/fakeit/validation/validation_error.rb
@@ -251,7 +285,7 @@ homepage: https://github.com/JustinFeng/fakeit
251
285
  licenses:
252
286
  - MIT
253
287
  metadata: {}
254
- post_install_message:
288
+ post_install_message:
255
289
  rdoc_options: []
256
290
  require_paths:
257
291
  - lib
@@ -259,15 +293,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
259
293
  requirements:
260
294
  - - ">="
261
295
  - !ruby/object:Gem::Version
262
- version: 2.7.0
296
+ version: 3.0.0
263
297
  required_rubygems_version: !ruby/object:Gem::Requirement
264
298
  requirements:
265
299
  - - ">="
266
300
  - !ruby/object:Gem::Version
267
301
  version: '0'
268
302
  requirements: []
269
- rubygems_version: 3.1.2
270
- signing_key:
303
+ rubygems_version: 3.2.3
304
+ signing_key:
271
305
  specification_version: 4
272
306
  summary: Create mock server from Openapi specification
273
307
  test_files: []
@@ -1,63 +0,0 @@
1
- module Fakeit
2
- module App
3
- class << self
4
- def create(spec_file, options)
5
- specification = Fakeit::Openapi::Specification.new(spec_file)
6
-
7
- proc do |env|
8
- request = Rack::Request.new(env)
9
- specification
10
- .operation(request.request_method.downcase.to_sym, request.path_info, options)
11
- .then { _1 ? handle(_1, request, options) : not_found }
12
- end
13
- end
14
-
15
- private
16
-
17
- def handle(operation, request, options)
18
- validate(operation, request)
19
- response(operation)
20
- rescue Fakeit::Validation::ValidationError => e
21
- Fakeit::Logger.warn(Rainbow(e.message).red)
22
- options.permissive ? response(operation) : error(e)
23
- end
24
-
25
- def error(err)
26
- [418, { 'Content-Type' => 'application/json' }, [{ message: err.message }.to_json]]
27
- end
28
-
29
- def not_found
30
- [404, {}, ['Not Found']]
31
- end
32
-
33
- def response(operation)
34
- [operation.status, operation.headers, [operation.body]]
35
- end
36
-
37
- def validate(operation, request)
38
- operation.validate(
39
- body: BodyParser.parse(request),
40
- params: parse_query(request.query_string),
41
- headers: headers(request)
42
- )
43
- end
44
-
45
- def headers(request)
46
- request
47
- .each_header
48
- .select { |k, _| k.start_with? 'HTTP_' }
49
- .map { |k, v| [k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-'), v] }
50
- .to_h
51
- end
52
-
53
- def parse_query(query_string)
54
- rack_query = Rack::Utils.parse_nested_query(query_string)
55
- cgi_query = CGI.parse(query_string)
56
-
57
- rack_query.merge(cgi_query.slice(*rack_query.keys)) do |_, oldval, newval|
58
- newval.is_a?(Array) && newval.size > 1 ? newval : oldval
59
- end
60
- end
61
- end
62
- end
63
- end
@@ -1,30 +0,0 @@
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