contracto 0.4.1 → 0.4.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
  SHA1:
3
- metadata.gz: 878cd05857b9fea82b17d7a5954073fe913f0dc5
4
- data.tar.gz: 9dff5a72b030781058855be8144a5ae4fde47f97
3
+ metadata.gz: c35eed00df100a4c4a2117e8a0d239cb20dcd117
4
+ data.tar.gz: a55bf9e05603df1c4b03cc354d34096945795d02
5
5
  SHA512:
6
- metadata.gz: d7a9e463e67cdc5e56c0e194f075bf0d685e3e29066d3faf5414c17ec15f97ac5da739611edaac3d09caed076428823019e4e00c7a360157a885b445a453286a
7
- data.tar.gz: 33451ca2f440f3ef74e8c016e5ff3496f66a1212c1972d2811f978470e8beea887d9f20256bcf370069cb7541fe36fe37d255fcea129c96b9b61c7bd36e1c1d5
6
+ metadata.gz: 43d467496a10704a35fec13b81d11b1a2ccf4d7e502a371748ae637df018e022191a8af6ef0fd3bcbf056c7730172b4d8ac04484341b4adbfc66512c11919143
7
+ data.tar.gz: bd325007dca162ebc8f9ae2e4d8c5455c9429ac0bacff26a4fdb003c0fef5a900449874cce5845815b719934d0eeb39466360e3fc3069d295d393ff8c1e33c6e
data/contracto.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_runtime_dependency 'daemons', '~> 1.2'
25
25
 
26
26
  spec.add_development_dependency 'rspec', '~> 3.2'
27
+ spec.add_development_dependency 'callapi', '~> 0.9'
27
28
  spec.add_development_dependency 'bundler', '~> 1.7'
28
29
  spec.add_development_dependency 'rake', '~> 10.0'
29
30
  end
@@ -4,7 +4,7 @@ class Contracto::Command::Start::Remote
4
4
  end
5
5
 
6
6
  def execute
7
- puts "downloading contract from #{Contracto::Config.repo_url}"
7
+ puts "downloading contract from #{Contracto::Config.repo_url} to #{Contracto::Config.root_dir}"
8
8
  Contracto::SystemActionChain.new(*actions).execute
9
9
  end
10
10
 
@@ -12,9 +12,7 @@ class Contracto::Command::Start::Remote
12
12
 
13
13
  def actions
14
14
  [
15
- :clone_repo_to_tmp_contracto_dir,
16
- :move_tmp_dir_files_to_root_dir,
17
- :remove_tmp_contracto_dir,
15
+ :clone_repo,
18
16
  :start_server
19
17
  ]
20
18
  end
@@ -12,6 +12,9 @@ class Contracto::Command
12
12
  Contracto::Command::Start.new(args).execute
13
13
  when 'stop'
14
14
  Contracto::Command::Stop.new(args).execute
15
+ when 'restart'
16
+ Contracto::Command::Stop.new(args).execute
17
+ Contracto::Command::Start.new(args).execute
15
18
  end
16
19
  end
17
20
  end
@@ -11,7 +11,11 @@ class Contracto::Config
11
11
  end
12
12
 
13
13
  def root_dir
14
- @root_dir || default_root_dir
14
+ @cached_root_dir ||= if @root_dir
15
+ "#{current_dir}/#{@root_dir}"
16
+ else
17
+ default_root_dir
18
+ end
15
19
  end
16
20
 
17
21
  end
@@ -2,7 +2,8 @@ module Contracto::Constants
2
2
  require 'fileutils'
3
3
 
4
4
  GEM_DIR = Gem::Specification.find_by_name('contracto').gem_dir
5
- DEFAULT_ROOT_DIR = FileUtils.pwd
5
+ CURRENT_DIR = FileUtils.pwd
6
+ DEFAULT_ROOT_DIR = CURRENT_DIR + '/.contract'
6
7
  CONTRACTO_DIR = '.contracto'
7
8
  CONTRACTO_TMP_DIR = '.tmp.contracto'
8
9
  RUBY_SERVER_DIR = "#{GEM_DIR}/lib/contracto/server/ruby"
@@ -13,6 +14,7 @@ module Contracto::Constants
13
14
 
14
15
  %w(
15
16
  gem_dir
17
+ current_dir
16
18
  default_root_dir
17
19
  contracto_dir
18
20
  contracto_tmp_dir
@@ -6,22 +6,49 @@ class Contracto::Contract::Response
6
6
  @hash = hash
7
7
  end
8
8
 
9
+ def request
10
+ @hash['request'] || {}
11
+ end
12
+
9
13
  def params
10
- @hash.fetch('request')['params'] || {} #TODO: should it be optional or required?
14
+ request['params'] || {} #TODO: should it be optional or required?
15
+ end
16
+
17
+ def headers
18
+ request['headers'] || {} #TODO: should it be optional or required?
11
19
  end
12
20
 
13
21
  def body_path
14
22
  @hash.fetch('response').fetch('body_path')
15
23
  end
16
24
 
17
- def params_matches?(other_params)
18
- return true if params.nil?
25
+ def params_matches?(request_params)
26
+ return true if params.empty?
19
27
 
20
28
  params.keys.all? do |key|
21
- other_params[key] == params[key].to_s
29
+ value_from_contract = params[key]
30
+ value_from_request = request_params[key]
31
+
32
+ if value_from_contract.is_a?(Numeric)
33
+ value_from_request = string_to_number(value_from_contract, value_from_request)
34
+ end
35
+
36
+ value_from_request == value_from_contract
37
+ end
38
+ end
39
+
40
+ def headers_matches?(other_headers)
41
+ return true if headers.empty?
42
+
43
+ headers.keys.all? do |key|
44
+ other_headers[human_header_key_to_http_header_key(key)] == headers[key]
22
45
  end
23
46
  end
24
47
 
48
+ def conditions_number
49
+ params.keys.size + headers.keys.size
50
+ end
51
+
25
52
  def body
26
53
  set_body
27
54
  @body.tap do
@@ -31,13 +58,26 @@ class Contracto::Contract::Response
31
58
 
32
59
  private
33
60
 
61
+ def string_to_number(number, string)
62
+ if number.is_a?(Integer)
63
+ string.to_i
64
+ elsif number.is_a?(Float)
65
+ string.to_f
66
+ end
67
+ end
68
+
34
69
  def set_body
35
70
  @body = File.read(Contracto::Config.root_dir + body_path)
36
71
  end
37
72
 
73
+ def human_header_key_to_http_header_key(key)
74
+ key = key.upcase
75
+ key = key.gsub('-', '_')
76
+ key = 'HTTP_' + key
77
+ key
78
+ end
79
+
38
80
  def replace_params_placeholders_with_params_value
39
- params.each do |key, value|
40
- @body.gsub!(":#{key}", value.to_s) if value
41
- end
81
+ # TODO
42
82
  end
43
83
  end
@@ -1,5 +1,8 @@
1
1
  class Contracto::Contract
2
2
  require_relative 'contract/response'
3
+ require_relative 'stats'
4
+
5
+ attr_reader :responses
3
6
 
4
7
  def initialize(hash)
5
8
  @hash = hash
@@ -15,19 +18,31 @@ class Contracto::Contract
15
18
  @request.url_pattern
16
19
  end
17
20
 
18
- def response_body(params)
19
- response = @responses.find_by_params(params)
21
+ def response_body(params, headers)
22
+ response = @responses.find_by_params_and_headers(params, headers)
20
23
  raise Contracto::ResponseNotFoundError.new(params) unless response
21
- response.body
24
+ response.body.tap do
25
+ Contracto::Stats.used_contracts << self unless Contracto::Stats.used_contracts.include?(self)
26
+ end
22
27
  end
23
28
 
24
29
  class Contracto::Contract::Responses
25
30
  def initialize(responses)
26
- @responses = responses.map { |response| Contracto::Contract::Response.new(response) }
31
+ @responses = responses.map do |response|
32
+ Contracto::Contract::Response.new(response)
33
+ end.sort_by(&:conditions_number).reverse
34
+ end
35
+
36
+ def find_by_params_and_headers(params, headers)
37
+ @responses.find do |response|
38
+ response.params_matches?(params) && response.headers_matches?(headers)
39
+ end.tap do |response|
40
+ Contracto::Stats.used_responses << response if response && !Contracto::Stats.used_responses.include?(response)
41
+ end
27
42
  end
28
43
 
29
- def find_by_params(params)
30
- @responses.find { |response| response.params_matches?(params) }
44
+ def count
45
+ @responses.count
31
46
  end
32
47
  end
33
48
 
@@ -1,15 +1,20 @@
1
1
  require 'json'
2
2
 
3
3
  class Contracto::Parser
4
+ require_relative 'stats'
5
+
4
6
  def initialize(strings_with_json)
5
7
  @json_collection = strings_with_json.map { |string| JSON.parse(string) }
6
8
  end
7
9
 
8
10
  def contracts
9
11
  @json_collection.map do |json|
10
- Array(json).map do |json|
12
+ json = [json] unless json.is_a?(Array)
13
+ json.map do |json|
11
14
  Contracto::Contract.new(json)
12
15
  end
13
- end.flatten
16
+ end.flatten.tap do |contracts|
17
+ Contracto::Stats.all_contracts = contracts
18
+ end
14
19
  end
15
20
  end
@@ -1,6 +1,7 @@
1
1
  require 'sinatra/base'
2
2
 
3
3
  class Contracto::Server < Sinatra::Base
4
+ require_relative '../../stats'
4
5
 
5
6
  set :port, Contracto::Constants::PORT
6
7
 
@@ -8,15 +9,58 @@ class Contracto::Server < Sinatra::Base
8
9
  "*** Contracto server is working! [#{Gem::Specification.find_by_name('contracto').version}] ***"
9
10
  end
10
11
 
12
+ get '/contracto_terminate' do
13
+ Thread.new { sleep 1; Process.kill 'INT', Process.pid }
14
+ status 200
15
+ body_on_terminate
16
+ end
17
+
11
18
  jsons_with_contracts = Dir["#{Contracto::Config.root_dir}/**/*.con.json"].map do |file_with_contract|
12
19
  File.read file_with_contract
13
20
  end
14
21
 
15
22
  Contracto::Parser.new(jsons_with_contracts).contracts.each do |contract|
16
23
  send(contract.http_method, contract.url_pattern) do
17
- contract.response_body(params)
24
+ begin
25
+ contract.response_body(params, http_headers)
26
+ rescue StandardError => ex
27
+ status 500
28
+ error_response(ex)
29
+ end
18
30
  end
19
31
  end
20
32
 
33
+ def http_headers
34
+ env.select {|k,v| k.start_with? 'HTTP_'}
35
+ end
36
+
37
+ def error_response(ex)
38
+ ["#{ex.class}: #{ex.message}", ex.backtrace[0, 15].join("\n")].join("\n")
39
+ end
40
+
41
+ def body_on_terminate
42
+ used_contracts_count = Contracto::Stats.used_contracts.size
43
+ all_contracts_count = Contracto::Stats.all_contracts.size
44
+ used_responses_count = Contracto::Stats.used_responses.size
45
+ all_responses_count = Contracto::Stats.all_responses.size
46
+
47
+ contracts_usage = if all_contracts_count.zero?
48
+ 'N/A'
49
+ else
50
+ "#{(used_contracts_count / all_contracts_count.to_f).round(2)}%"
51
+ end
52
+
53
+ responses_usage = if all_responses_count.zero?
54
+ 'N/A'
55
+ else
56
+ "#{(used_responses_count / all_responses_count.to_f).round(2)}%"
57
+ end
58
+
59
+ [
60
+ "Used contracts: #{used_contracts_count}/#{all_contracts_count} (#{contracts_usage})",
61
+ "Used responses: #{used_responses_count}/#{all_responses_count} (#{responses_usage})",
62
+ ''
63
+ ].join("\n")
64
+ end
21
65
  end
22
66
 
@@ -0,0 +1,17 @@
1
+ class Contracto::Stats
2
+ class << self
3
+ attr_accessor :all_contracts
4
+
5
+ def used_contracts
6
+ @used_contracts ||= []
7
+ end
8
+
9
+ def used_responses
10
+ @used_responses ||= []
11
+ end
12
+
13
+ def all_responses
14
+ @all_responses ||= all_contracts.map(&:responses).map(&:count).inject(&:+)
15
+ end
16
+ end
17
+ end
@@ -4,20 +4,18 @@ class Contracto::SystemAction
4
4
  class << self
5
5
  include Contracto::Constants
6
6
 
7
- def remove_tmp_contracto_dir
8
- FileUtils.rm_rf contracto_tmp_dir
9
- end
10
-
11
7
  def create_sample_contract
12
- if contract_already_exists?
8
+ if Dir.exists?(Contracto::Config.root_dir)
13
9
  puts 'contract already exists, creating sample contract skipped'
14
10
  else
15
- FileUtils.cp_r sample_contract_dir, contracto_tmp_dir
16
- move_tmp_dir_files_to_root_dir
17
- puts "created: #{contract_filename}"
11
+ FileUtils.cp_r sample_contract_dir, Contracto::Config.root_dir
18
12
  end
19
13
  end
20
14
 
15
+ def revert_create_sample_contract
16
+ remove_root_dir
17
+ end
18
+
21
19
  def start_server
22
20
  raise Contracto::ServerAlreadyRunningError if server_already_running?
23
21
 
@@ -43,10 +41,8 @@ class Contracto::SystemAction
43
41
 
44
42
  def stop_server
45
43
  puts 'killing server...'
46
- Process.kill(15, File.read("#{Contracto::Config.root_dir}/#{server_pidfile_name}.pid").to_i)
44
+ system "curl 0.0.0.0:#{port}/contracto_terminate"
47
45
  puts '...server killed'
48
- rescue Errno::ENOENT
49
- puts 'could not kill server (pidfile not found)'
50
46
  end
51
47
 
52
48
  def revert_start_server
@@ -54,27 +50,20 @@ class Contracto::SystemAction
54
50
  rescue StandardError
55
51
  end
56
52
 
57
- def clone_repo_to_tmp_contracto_dir
58
- success = system "git clone -q --depth 1 --single-branch --branch master #{Contracto::Config.repo_url} #{contracto_tmp_dir}"
53
+ def clone_repo
54
+ FileUtils.rm_rf Contracto::Config.root_dir
55
+ success = system "git clone -q --depth 1 --single-branch --branch master #{Contracto::Config.repo_url} #{Contracto::Config.root_dir}"
59
56
  raise(Contracto::CouldNotDownloadContractError.new(Contracto::Config.repo_url)) unless success
60
57
  end
61
58
 
62
- def revert_clone_repo_to_tmp_contracto_dir
63
- remove_tmp_contracto_dir
59
+ def revert_clone_repo
60
+ remove_root_dir
64
61
  end
65
62
 
66
- def move_tmp_dir_files_to_root_dir
67
- move_dir_files_to_root_dir(contracto_tmp_dir)
68
- end
69
-
70
63
  private
71
64
 
72
- def move_dir_files_to_root_dir(dir)
73
- system "mv #{dir}/* #{dir}/.[^.]* . 2> /dev/null" # Could not use FileUtils for some reason
74
- end
75
-
76
- def contract_already_exists?
77
- File.exist?("#{Contracto::Config.root_dir}/#{contract_filename}")
65
+ def remove_root_dir
66
+ FileUtils.rm_rf Contracto::Config.root_dir
78
67
  end
79
68
 
80
69
  def server_already_running?
@@ -1,3 +1,3 @@
1
1
  module Contracto
2
- VERSION = '0.4.1'
2
+ VERSION = '0.4.2'
3
3
  end
@@ -0,0 +1,33 @@
1
+ {
2
+ "request": {
3
+ "http_method": "get",
4
+ "path": "/users"
5
+ },
6
+ "responses": [
7
+ {
8
+ "request": {
9
+ "params": {
10
+ "search": "Albert"
11
+ }
12
+ },
13
+ "response": {
14
+ "body_path": "/users/get_users_by_search_search_albert.json"
15
+ }
16
+ },
17
+ {
18
+ "request": {
19
+ "headers": {
20
+ "Content-Type": "application/xml"
21
+ }
22
+ },
23
+ "response": {
24
+ "body_path": "/users/get_users.xml"
25
+ }
26
+ },
27
+ {
28
+ "response": {
29
+ "body_path": "/users/get_users.json"
30
+ }
31
+ }
32
+ ]
33
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "request": {
3
+ "http_method": "get",
4
+ "path": "/users/:id"
5
+ },
6
+ "responses": [
7
+ {
8
+ "request": {
9
+ "params": {
10
+ "id": 1
11
+ }
12
+ },
13
+ "response": {
14
+ "body_path": "/users/get_users_by_id_id_1.json"
15
+ }
16
+ },
17
+ {
18
+ "request": {
19
+ "params": {
20
+ "id": 2
21
+ }
22
+ },
23
+ "response": {
24
+ "body_path": "/users/get_users_by_id_id_2.json"
25
+ }
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "request": {
3
+ "http_method": "get",
4
+ "path": "/my/data",
5
+ "meta": {
6
+ "request": {
7
+
8
+ },
9
+ "response": {
10
+ "body": {
11
+ "type": "object",
12
+ "embedded": [
13
+ {
14
+ "name": "id",
15
+ "type": "string"
16
+ }
17
+ ]
18
+ }
19
+ }
20
+ }
21
+ },
22
+ "responses": []
23
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "request": {
3
+ "http_method": "post",
4
+ "path": "/users"
5
+ },
6
+ "responses": [
7
+ {
8
+ "request": {
9
+ "params": {
10
+ "user": {
11
+ "first_name": "New",
12
+ "last_name": "User",
13
+ "age": "30"
14
+ }
15
+ }
16
+ },
17
+ "response": {
18
+ "body_path": "/users/post_users.json"
19
+ }
20
+ }
21
+ ]
22
+ }
File without changes
@@ -0,0 +1,14 @@
1
+ <users type="array">
2
+ <user>
3
+ <id type="integer">1</id>
4
+ <first-name>Albert</first-name>
5
+ <last-name>Einstein</last-name>
6
+ <age type="integer">30</age>
7
+ </user>
8
+ <user>
9
+ <id type="integer">2</id>
10
+ <first-name>Kurt</first-name>
11
+ <last-name>Godel</last-name>
12
+ <age type="integer">35</age>
13
+ </user>
14
+ </users>
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": :id,
2
+ "id": 1,
3
3
  "first_name": "Albert",
4
4
  "last_name": "Einstein",
5
5
  "age": 30
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": :id,
2
+ "id": 2,
3
3
  "first_name": "Kurt",
4
4
  "last_name": "Godel",
5
5
  "age": 35
@@ -0,0 +1,7 @@
1
+ [
2
+ {
3
+ "first_name": "Albert",
4
+ "last_name": "Einstein",
5
+ "age": 30
6
+ }
7
+ ]
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": 111,
3
+ "first_name": "New",
4
+ "last_name": "User",
5
+ "age": 30
6
+ }
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,24 @@
1
1
  require_relative '../lib/contracto'
2
+ require 'callapi'
2
3
 
3
- STRINGS_WITH_JSON = [File.read('spec/fixtures/contract.con.json')]
4
+ Contracto::Config.root_dir = 'spec/fixtures'
5
+ Contracto::Command.run('start', [])
4
6
 
5
7
  RSpec.configure do |config|
6
- config.before(:each) do
7
- allow_any_instance_of(Contracto::Constants).to receive(:root_dir).and_return FileUtils.pwd + '/spec/fixtures'
8
+ config.before(:suite) do
9
+
10
+ Callapi::Config.api_host = 'http://0.0.0.0:54321'
11
+ Callapi::Config.log_level = :none
12
+
13
+ Callapi::Routes.draw do
14
+ get 'users'
15
+ post 'users'
16
+ get 'users/:id'
17
+ get 'users/:id/posts'
18
+ end
19
+ end
20
+
21
+ config.after(:suite) do
22
+ Contracto::Command.run('stop', [])
8
23
  end
9
24
  end
@@ -1,43 +1,56 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe Contracto::Contract do
3
+ RSpec.describe 'Contracto' do
4
4
 
5
- context '#http_method' do
6
- let(:contract) { contracts[1] }
7
- subject { contract.http_method }
8
-
9
- it { expect(subject).to eq 'get' }
10
- end
11
-
12
- context '#url_pattern' do
13
- let(:contract) { contracts[1] }
14
- subject { contract.url_pattern }
5
+ context 'HTTP methods' do
6
+ it 'should return response with GET' do
7
+ expect(get_users_call.data).to eq [{"first_name"=>"Albert", "last_name"=>"Einstein", "age"=>30}, {"first_name"=>"Kurt", "last_name"=>"Godel", "age"=>35}]
8
+ end
15
9
 
16
- it { expect(subject).to eq '/users/:id' }
10
+ it 'should return response with POST' do
11
+ # TODO
12
+ end
17
13
  end
18
14
 
19
- context '#response_body' do
20
-
15
+ context 'selecting response' do
21
16
  context 'by params' do
17
+ it 'should find response by one string param' do
18
+ expect(get_users_call(search: 'Albert').data).to eq [{"first_name"=>"Albert", "last_name"=>"Einstein", "age"=>30}]
19
+ end
22
20
 
23
- let(:contract) { contracts[1] }
24
- let(:response_0) { JSON.parse contract.response_body('id' => '1', 'foo' => 'bar') }
25
- let(:response_1) { JSON.parse contract.response_body('id' => '2') }
26
-
27
- it 'should return body based on params' do
28
- expect(response_0).to eq('first_name' => 'Albert', 'last_name' => 'Einstein', 'age' => 30)
29
- expect(response_1).to eq('first_name' => 'Kurt', 'last_name' => 'Godel', 'age' => 35)
21
+ it 'should find response by one integer param' do
22
+ expect(get_users_by_id_call(id: 1).data).to eq("id"=>1, "first_name"=>"Albert", "last_name"=>"Einstein", "age"=>30)
30
23
  end
31
24
 
32
- it 'should raise "ResponseNotFound" exception if no response matches params' do
33
- expect{ contract.response_body('id' => '-1') }.to raise_error(Contracto::ResponseNotFoundError)
25
+ it 'should find response by one hash param' do
26
+ expect(post_users_call('user[first_name]' => 'New', 'user[last_name]' => 'User', 'user[age]' => '30').data).to eq("id"=>111, "first_name"=>"New", "last_name"=>"User", "age"=>30)
34
27
  end
35
28
  end
36
29
 
37
- end
38
-
39
- def contracts
40
- Contracto::Parser.new(STRINGS_WITH_JSON).contracts
30
+ context 'by headers' do
31
+ it 'should find response by header' do
32
+ expected = <<XML
33
+ <users type="array">
34
+ <user>
35
+ <id type="integer">1</id>
36
+ <first-name>Albert</first-name>
37
+ <last-name>Einstein</last-name>
38
+ <age type="integer">30</age>
39
+ </user>
40
+ <user>
41
+ <id type="integer">2</id>
42
+ <first-name>Kurt</first-name>
43
+ <last-name>Godel</last-name>
44
+ <age type="integer">35</age>
45
+ </user>
46
+ </users>
47
+ XML
48
+
49
+ given = get_users_call.add_headers({"Content_Type" => "application/xml"}).body.gsub!(/\s+/, "")
50
+ expected = expected.gsub!(/\s+/, "")
51
+ expect(given).to eq expected
52
+ end
53
+ end
41
54
  end
42
55
 
43
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contracto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kacper Walanus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-16 00:00:00.000000000 Z
11
+ date: 2015-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: callapi
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -110,22 +124,25 @@ files:
110
124
  - lib/contracto/parser.rb
111
125
  - lib/contracto/server/ruby/config.ru
112
126
  - lib/contracto/server/ruby/server.rb
127
+ - lib/contracto/stats.rb
113
128
  - lib/contracto/system_action.rb
114
129
  - lib/contracto/system_action_chain.rb
115
130
  - lib/contracto/version.rb
116
131
  - script/send_test_requests.sh
117
132
  - script/start_from_remote.sh
118
133
  - script/start_locally.sh
119
- - spec/fixtures/contract.con.json
120
- - spec/fixtures/posts.con.json
121
- - spec/fixtures/users.json
122
- - spec/fixtures/users/1.json
123
- - spec/fixtures/users/1/posts.json
124
- - spec/fixtures/users/2.json
125
- - spec/fixtures/users/2/posts.json
134
+ - spec/fixtures/get_users.con.json
135
+ - spec/fixtures/get_users_by_id.con.json
136
+ - spec/fixtures/my_data.con.json
137
+ - spec/fixtures/post_users.con.json
138
+ - spec/fixtures/users/get_users.json
139
+ - spec/fixtures/users/get_users.xml
140
+ - spec/fixtures/users/get_users_by_id_id_1.json
141
+ - spec/fixtures/users/get_users_by_id_id_2.json
142
+ - spec/fixtures/users/get_users_by_search_search_albert.json
143
+ - spec/fixtures/users/post_users.json
126
144
  - spec/spec_helper.rb
127
145
  - spec/unit/contract_spec.rb
128
- - spec/unit/parser_spec.rb
129
146
  homepage: ''
130
147
  licenses:
131
148
  - MIT
@@ -151,13 +168,15 @@ signing_key:
151
168
  specification_version: 4
152
169
  summary: XXX
153
170
  test_files:
154
- - spec/fixtures/contract.con.json
155
- - spec/fixtures/posts.con.json
156
- - spec/fixtures/users.json
157
- - spec/fixtures/users/1.json
158
- - spec/fixtures/users/1/posts.json
159
- - spec/fixtures/users/2.json
160
- - spec/fixtures/users/2/posts.json
171
+ - spec/fixtures/get_users.con.json
172
+ - spec/fixtures/get_users_by_id.con.json
173
+ - spec/fixtures/my_data.con.json
174
+ - spec/fixtures/post_users.con.json
175
+ - spec/fixtures/users/get_users.json
176
+ - spec/fixtures/users/get_users.xml
177
+ - spec/fixtures/users/get_users_by_id_id_1.json
178
+ - spec/fixtures/users/get_users_by_id_id_2.json
179
+ - spec/fixtures/users/get_users_by_search_search_albert.json
180
+ - spec/fixtures/users/post_users.json
161
181
  - spec/spec_helper.rb
162
182
  - spec/unit/contract_spec.rb
163
- - spec/unit/parser_spec.rb
@@ -1,54 +0,0 @@
1
- [
2
- {
3
- "request": {
4
- "http_method": "get",
5
- "path": "/users"
6
- },
7
- "responses": [
8
- {
9
- "request": {
10
- "headers": {
11
- "Content-Type": "application/json"
12
- }
13
- },
14
- "response": {
15
- "body_path": "/users.json"
16
- }
17
- }
18
- ]
19
- },
20
- {
21
- "request": {
22
- "http_method": "get",
23
- "path": "/users/:id"
24
- },
25
- "responses": [
26
- {
27
- "request": {
28
- "headers": {
29
- "Content-Type": "application/json"
30
- },
31
- "params": {
32
- "id": 1
33
- }
34
- },
35
- "response": {
36
- "body_path": "/users/1.json"
37
- }
38
- },
39
- {
40
- "request": {
41
- "headers": {
42
- "Content-Type": "application/json"
43
- },
44
- "params": {
45
- "id": 2
46
- }
47
- },
48
- "response": {
49
- "body_path": "/users/2.json"
50
- }
51
- }
52
- ]
53
- }
54
- ]
@@ -1,36 +0,0 @@
1
- [
2
- {
3
- "request": {
4
- "http_method": "get",
5
- "path": "/users/:id/posts"
6
- },
7
- "responses": [
8
- {
9
- "request": {
10
- "headers": {
11
- "Content-Type": "application/json"
12
- },
13
- "params": {
14
- "id": 1
15
- }
16
- },
17
- "response": {
18
- "body_path": "/users/1/posts.json"
19
- }
20
- },
21
- {
22
- "request": {
23
- "headers": {
24
- "Content-Type": "application/json"
25
- },
26
- "params": {
27
- "id": 2
28
- }
29
- },
30
- "response": {
31
- "body_path": "/users/2/posts.json"
32
- }
33
- }
34
- ]
35
- }
36
- ]
@@ -1,7 +0,0 @@
1
- [
2
- {
3
- "id": 1,
4
- "title": "When I got home",
5
- "content": "I killed my wife"
6
- }
7
- ]
@@ -1,7 +0,0 @@
1
- [
2
- {
3
- "id": 5,
4
- "title": "I had fun once",
5
- "content": "It was awful"
6
- }
7
- ]
@@ -1,12 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Contracto::Parser do
4
- context '#contracts' do
5
- subject { described_class.new(STRINGS_WITH_JSON).contracts }
6
-
7
- it do
8
- expect(subject).to be_a Array
9
- expect(subject.first).to be_a Contracto::Contract
10
- end
11
- end
12
- end