api_sim 2.2.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/examples/basic/Gemfile +3 -0
- data/examples/basic/Gemfile.lock +36 -0
- data/{config.example.ru → examples/basic/config.ru} +1 -1
- data/examples/cors/Gemfile +4 -0
- data/examples/cors/Gemfile.lock +38 -0
- data/examples/cors/README.md +6 -0
- data/examples/cors/config.ru +19 -0
- data/examples/with-fixtures/Gemfile +3 -0
- data/examples/with-fixtures/Gemfile.lock +36 -0
- data/examples/with-fixtures/config.ru +30 -0
- data/examples/with-fixtures/data/users/1/GET.json +17 -0
- data/lib/api_sim/built_app.rb +2 -2
- data/lib/api_sim/matchers/base_matcher.rb +13 -0
- data/lib/api_sim/matchers/dynamic_request_matcher.rb +2 -2
- data/lib/api_sim/matchers/static_request_matcher.rb +2 -20
- data/lib/api_sim/version.rb +1 -1
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b861496c5eace589914cf22783667e76a98b9e58
|
4
|
+
data.tar.gz: 18936141652259c619b2432669a2b926ffe33997
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6916e181541ce761dd3fdf4182efc6e2b0f45ebf0c2e61aa893f7b8e5e27e5be9e41454827f3a3c43b1156e5673c0adce7ab30db76a715821266cb717e903f44
|
7
|
+
data.tar.gz: d4518904d1c87e9684ed66453cafe275991ed4dd0f5f544f6d48a67407c8763679bc2a715827e7c8c2b4381cded513aa085f6fa149d5424bb571a12bc42f0b65
|
data/README.md
CHANGED
@@ -25,7 +25,7 @@ Or install it yourself as:
|
|
25
25
|
```ruby
|
26
26
|
require 'api_sim'
|
27
27
|
|
28
|
-
ENDPOINT_JSON_SCHEMA = {
|
28
|
+
ENDPOINT_JSON_SCHEMA = {type: "object", properties: {a: {type: "integer"}}}.to_json
|
29
29
|
|
30
30
|
app = ApiSim.build_app do
|
31
31
|
configure_endpoint 'GET', '/endpoint', 'Hi!', 200, {'X-CUSTOM-HEADER' => 'easy as abc'}, ENDPOINT_JSON_SCHEMA
|
@@ -43,11 +43,11 @@ end
|
|
43
43
|
run app
|
44
44
|
```
|
45
45
|
|
46
|
-
The above is an exact copy of the `config.
|
46
|
+
The above is an exact copy of the `basic/config.ru` from the examples. You can boot this without too much
|
47
47
|
effort by running:
|
48
48
|
|
49
49
|
```bash
|
50
|
-
bundle check || bundle install && bundle exec rackup -
|
50
|
+
cd examples/basic && bundle check || bundle install && bundle exec rackup -I../../lib
|
51
51
|
```
|
52
52
|
|
53
53
|
After which the simulators should be running on port 9292.
|
@@ -0,0 +1,36 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../
|
3
|
+
specs:
|
4
|
+
api_sim (2.2.0)
|
5
|
+
json-schema (>= 2.5)
|
6
|
+
nokogiri (~> 1.6.7)
|
7
|
+
sinatra (~> 1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.3.8)
|
13
|
+
json-schema (2.6.2)
|
14
|
+
addressable (~> 2.3.8)
|
15
|
+
mini_portile2 (2.1.0)
|
16
|
+
nokogiri (1.6.8)
|
17
|
+
mini_portile2 (~> 2.1.0)
|
18
|
+
pkg-config (~> 1.1.7)
|
19
|
+
pkg-config (1.1.7)
|
20
|
+
rack (1.6.4)
|
21
|
+
rack-protection (1.5.3)
|
22
|
+
rack
|
23
|
+
sinatra (1.4.7)
|
24
|
+
rack (~> 1.5)
|
25
|
+
rack-protection (~> 1.4)
|
26
|
+
tilt (>= 1.3, < 3)
|
27
|
+
tilt (2.0.5)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
api_sim!
|
34
|
+
|
35
|
+
BUNDLED WITH
|
36
|
+
1.12.5
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'api_sim'
|
2
2
|
|
3
|
-
ENDPOINT_JSON_SCHEMA = {
|
3
|
+
ENDPOINT_JSON_SCHEMA = {type: "object", properties: {a: {type: "integer"}}}.to_json
|
4
4
|
|
5
5
|
app = ApiSim.build_app do
|
6
6
|
configure_endpoint 'GET', '/endpoint', 'Hi!', 200, {'X-CUSTOM-HEADER' => 'easy as abc'}, ENDPOINT_JSON_SCHEMA
|
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../
|
3
|
+
specs:
|
4
|
+
api_sim (2.2.0)
|
5
|
+
json-schema (>= 2.5)
|
6
|
+
nokogiri (~> 1.6.7)
|
7
|
+
sinatra (~> 1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.3.8)
|
13
|
+
json-schema (2.6.2)
|
14
|
+
addressable (~> 2.3.8)
|
15
|
+
mini_portile2 (2.1.0)
|
16
|
+
nokogiri (1.6.8)
|
17
|
+
mini_portile2 (~> 2.1.0)
|
18
|
+
pkg-config (~> 1.1.7)
|
19
|
+
pkg-config (1.1.7)
|
20
|
+
rack (1.6.4)
|
21
|
+
rack-cors (0.4.0)
|
22
|
+
rack-protection (1.5.3)
|
23
|
+
rack
|
24
|
+
sinatra (1.4.7)
|
25
|
+
rack (~> 1.5)
|
26
|
+
rack-protection (~> 1.4)
|
27
|
+
tilt (>= 1.3, < 3)
|
28
|
+
tilt (2.0.5)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
api_sim!
|
35
|
+
rack-cors
|
36
|
+
|
37
|
+
BUNDLED WITH
|
38
|
+
1.12.5
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# CORS Example for APISim
|
2
|
+
|
3
|
+
As a fairly common usecase for things like this is to simulate APIs for static UI apps,
|
4
|
+
this example shows how you can use the Rack Middleware Rack-CORS to setup CORS support.
|
5
|
+
|
6
|
+
Like the other examples, you can just copy and paste this, and tweak to your liking.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rack/cors'
|
2
|
+
require 'api_sim'
|
3
|
+
|
4
|
+
app = ApiSim.build_app do
|
5
|
+
configure_endpoint 'GET', '/endpoint', 'Hi!', 200, {'X-CUSTOM-HEADER' => 'easy as abc'}
|
6
|
+
end
|
7
|
+
|
8
|
+
# See the documentation for Rack::Cors for all the options here.
|
9
|
+
use Rack::Cors do
|
10
|
+
allow do
|
11
|
+
origins '*'
|
12
|
+
resource '/*',
|
13
|
+
:methods => [:get, :post, :delete, :put, :patch, :options, :head],
|
14
|
+
:headers => :any,
|
15
|
+
:max_age => 600
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
run app
|
@@ -0,0 +1,36 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../
|
3
|
+
specs:
|
4
|
+
api_sim (2.2.0)
|
5
|
+
json-schema (>= 2.5)
|
6
|
+
nokogiri (~> 1.6.7)
|
7
|
+
sinatra (~> 1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.3.8)
|
13
|
+
json-schema (2.6.2)
|
14
|
+
addressable (~> 2.3.8)
|
15
|
+
mini_portile2 (2.1.0)
|
16
|
+
nokogiri (1.6.8)
|
17
|
+
mini_portile2 (~> 2.1.0)
|
18
|
+
pkg-config (~> 1.1.7)
|
19
|
+
pkg-config (1.1.7)
|
20
|
+
rack (1.6.4)
|
21
|
+
rack-protection (1.5.3)
|
22
|
+
rack
|
23
|
+
sinatra (1.4.7)
|
24
|
+
rack (~> 1.5)
|
25
|
+
rack-protection (~> 1.4)
|
26
|
+
tilt (>= 1.3, < 3)
|
27
|
+
tilt (2.0.5)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
api_sim!
|
34
|
+
|
35
|
+
BUNDLED WITH
|
36
|
+
1.12.5
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'api_sim'
|
2
|
+
require 'find'
|
3
|
+
|
4
|
+
DATA_DIR = File.expand_path('./data', __dir__)
|
5
|
+
endpoints = []
|
6
|
+
Find.find(DATA_DIR) do |path|
|
7
|
+
next if Dir.exist?(path) # Skip directories
|
8
|
+
http_method = File.basename(path, '.json') # our files are their HTTP method with the mime-type as the extension
|
9
|
+
route = File.dirname(path).gsub(DATA_DIR, '') # the endpoint URL is everything else
|
10
|
+
response = JSON.parse(File.read(path))
|
11
|
+
status = response['status']
|
12
|
+
headers = response['headers']
|
13
|
+
body = response['body'].to_json
|
14
|
+
schema = response['schema'].to_json
|
15
|
+
puts "Configuring endpoint #{http_method} #{route}"
|
16
|
+
endpoints << [
|
17
|
+
http_method,
|
18
|
+
route,
|
19
|
+
body,
|
20
|
+
status,
|
21
|
+
headers,
|
22
|
+
schema
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
app = ApiSim.build_app do
|
27
|
+
endpoints.each {|endpoint| configure_endpoint(*endpoint) }
|
28
|
+
end
|
29
|
+
|
30
|
+
run app
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"status": 201,
|
3
|
+
"body": {
|
4
|
+
"id": 1,
|
5
|
+
"name": "Polly Peppers"
|
6
|
+
},
|
7
|
+
"headers": {
|
8
|
+
"Content-Type": "application/json"
|
9
|
+
},
|
10
|
+
"schema": {
|
11
|
+
"type": "object",
|
12
|
+
"properties": {
|
13
|
+
"id": {"type": "integer"},
|
14
|
+
"name": {"type": "string"}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
data/lib/api_sim/built_app.rb
CHANGED
@@ -36,7 +36,7 @@ module ApiSim
|
|
36
36
|
post '/ui/response/:method/*' do
|
37
37
|
@config = matcher(faux_request(http_method, route, faux_body))
|
38
38
|
unless params['schema'].empty?
|
39
|
-
@errors = JSON::Validator.fully_validate(params['schema'], params['body'])
|
39
|
+
@errors = JSON::Validator.fully_validate(JSON.parse(params['schema']), params['body'])
|
40
40
|
if @errors.any?
|
41
41
|
return erb :'responses/form.html', layout: :'layout.html'
|
42
42
|
end
|
@@ -79,7 +79,7 @@ module ApiSim
|
|
79
79
|
endpoint.requests.to_json
|
80
80
|
end
|
81
81
|
|
82
|
-
%i(get post put patch delete).each do |http_method|
|
82
|
+
%i(get post put patch delete options).each do |http_method|
|
83
83
|
public_send(http_method, '/*') do
|
84
84
|
endpoint = matcher(request)
|
85
85
|
endpoint.record_request(request)
|
@@ -49,6 +49,19 @@ module ApiSim
|
|
49
49
|
def response(_)
|
50
50
|
[response_code, headers, response_body]
|
51
51
|
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def matches_route_pattern?(request)
|
56
|
+
route_tokens = route.split('/')
|
57
|
+
request_tokens = request.path.split('/')
|
58
|
+
|
59
|
+
return false if route_tokens.count != request_tokens.count && !route_tokens.include?('*')
|
60
|
+
route_tokens.zip(request_tokens).all? do |matcher_part, request_part|
|
61
|
+
break true if matcher_part == '*'
|
62
|
+
matcher_part == request_part || matcher_part.start_with?(':')
|
63
|
+
end
|
64
|
+
end
|
52
65
|
end
|
53
66
|
end
|
54
67
|
end
|
@@ -15,7 +15,7 @@ module ApiSim
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def matches?(request)
|
18
|
-
request
|
18
|
+
matches_route_pattern?(request) && request.request_method == http_method && matcher.call(request)
|
19
19
|
end
|
20
20
|
|
21
21
|
def response(request)
|
@@ -33,4 +33,4 @@ module ApiSim
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
-
end
|
36
|
+
end
|
@@ -18,11 +18,7 @@ module ApiSim
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def matches?(request)
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def custom_matcher?
|
25
|
-
matcher != ALWAYS_TRUE_MATCHER
|
21
|
+
matches_route_pattern?(request) && request.request_method == http_method && matcher.call(request)
|
26
22
|
end
|
27
23
|
|
28
24
|
def overridden!
|
@@ -33,25 +29,11 @@ module ApiSim
|
|
33
29
|
!!@overridden
|
34
30
|
end
|
35
31
|
|
36
|
-
def requests
|
37
|
-
@requests ||= []
|
38
|
-
end
|
39
|
-
|
40
32
|
def to_s
|
41
33
|
<<-DOC.gsub(/^\s+/, '')
|
42
34
|
#{http_method} #{route} -> (#{response_code}) #{response_body[0..20]}...
|
43
35
|
DOC
|
44
36
|
end
|
45
|
-
|
46
|
-
def matches_dynamic_path?(request)
|
47
|
-
route_tokens = route.split('/')
|
48
|
-
request_tokens = request.path.split('/')
|
49
|
-
|
50
|
-
return false unless route_tokens.count == request_tokens.count
|
51
|
-
route_tokens.zip(request_tokens).all? do |matcher_part, request_part|
|
52
|
-
matcher_part == request_part || matcher_part.start_with?(':')
|
53
|
-
end
|
54
|
-
end
|
55
37
|
end
|
56
38
|
end
|
57
|
-
end
|
39
|
+
end
|
data/lib/api_sim/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_sim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TJ Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -126,7 +126,17 @@ files:
|
|
126
126
|
- api_sim.gemspec
|
127
127
|
- bin/console
|
128
128
|
- bin/setup
|
129
|
-
-
|
129
|
+
- examples/basic/Gemfile
|
130
|
+
- examples/basic/Gemfile.lock
|
131
|
+
- examples/basic/config.ru
|
132
|
+
- examples/cors/Gemfile
|
133
|
+
- examples/cors/Gemfile.lock
|
134
|
+
- examples/cors/README.md
|
135
|
+
- examples/cors/config.ru
|
136
|
+
- examples/with-fixtures/Gemfile
|
137
|
+
- examples/with-fixtures/Gemfile.lock
|
138
|
+
- examples/with-fixtures/config.ru
|
139
|
+
- examples/with-fixtures/data/users/1/GET.json
|
130
140
|
- lib/api_sim.rb
|
131
141
|
- lib/api_sim/app_builder.rb
|
132
142
|
- lib/api_sim/built_app.rb
|