blueprint_agreement 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b05de0aada665a43509a4e8fe98ccc07b5af9033
4
+ data.tar.gz: 2da0ab1502163df9f913a44e04ac8aa11e17093a
5
+ SHA512:
6
+ metadata.gz: d5bcb4201a35022d0ebd95877a0e8066d293e162c40ff8882dee4d09a4926ab49248b8d99cd1938991a3a91cc1dd89bb1258930382aaffc34e0a1acb279b234d
7
+ data.tar.gz: 41ac19df8f3ddb8249c27ad9d073e9f53db68423aafcca0f877b04afe8353230e3bcae58df2d84c1c9af9d8664196b32b98c4aed59b57f91bb7fd5f148c21c58
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+ .byebug_history
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.0
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+ rvm:
5
+ - 2.2.4
6
+ - 2.3.0
7
+ install:
8
+ - bundle install
9
+ - npm install drakov
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in agreement.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Charly Palencia
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # Blueprint Agreement
2
+
3
+ A Minitest API Documentation Matcher based on ApiBluePrint schema.
4
+
5
+ Note: This Gem Is Currently on Development.
6
+
7
+ ## Description
8
+
9
+ - A ruby library for Validate API Blueprint Documentation
10
+ - Support MiniTest Assertion and Spec format
11
+ - Use drakov node library to serve Mock API server
12
+
13
+
14
+ ## Getting Started
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'blueprint-agreement'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install agreement
27
+
28
+ *MiniTest*
29
+
30
+ ```ruby
31
+ require 'blueprint_agreement'
32
+ ```
33
+
34
+ ## Usage
35
+
36
+ ### Quick Start
37
+
38
+ Blueprint agreement works based on a markdown file with an valid API Blueprint format. Add your file into `/docs` folder in your project root folder (or set your custom documentation folder)
39
+
40
+ ./docs/test.md
41
+
42
+ ```
43
+ FORMAT: 1A
44
+
45
+ # The Simplest API
46
+
47
+ ## API Blueprint
48
+
49
+ # GET /message
50
+ + Request 200 (application/json)
51
+ + Response 200 (application/json)
52
+
53
+ + Body
54
+
55
+ {
56
+ 'name': 'Hello World'
57
+ }
58
+
59
+ ```
60
+
61
+ Then, test your documentation:
62
+
63
+ ``` ruby
64
+
65
+ describe Test do
66
+ it 'has a valid response' do
67
+ get :index
68
+ response.shall_agree_with('test.md')
69
+ end
70
+ end
71
+ ```
72
+
73
+ ### Config File
74
+
75
+ /config/initializer/blueprint_agreement.rb
76
+
77
+ ``` ruby
78
+ BlueprintAgreement::Config.port = '8081' #Default port for Drakov Server
79
+ BlueprintAgreement::Config.server_path= './docs' #Default server path for Drakov Server
80
+ ```
81
+
82
+
83
+ ## Contributing
84
+
85
+ 1. Fork it ( http://github.com/charly-palencia/agreement/fork )
86
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
87
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
88
+ 4. Push to the branch (`git push origin my-new-feature`)
89
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ ROOT_PATH = File.dirname(__FILE__)
2
+ Dir[ File.join(ROOT_PATH, "tasks/**/*.rake")].sort.each { |ext| load ext }
3
+ require "bundler/gem_tasks"
4
+
5
+ task default: [:test]
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'blueprint_agreement/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "blueprint_agreement".freeze
8
+ spec.version = BlueprintAgreement::VERSION
9
+ spec.authors = ["Charly Palencia"]
10
+ spec.email = ["charly.palencia@koombea.com"]
11
+ spec.summary = %q{A Minitest API Documentation Matcher , based on ApiBluePrint schema.}
12
+ spec.description = %q{A Minitest API Documentation Matcher , based on ApiBluePrint schema.}
13
+ spec.homepage = "http://www.chalien.com"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake", "~>11.1"
23
+ spec.add_development_dependency 'minitest', "~>5.9"
24
+ spec.add_development_dependency 'mocha', "~>1.1"
25
+ spec.add_development_dependency 'byebug', "~>9.0"
26
+ end
@@ -0,0 +1,43 @@
1
+ module BlueprintAgreement
2
+ class DrakovService
3
+ attr :pid, :port, :hostname, :root_path
4
+
5
+ def initialize(hostname = 'http://localhost')
6
+ @port = Config.port
7
+ @hostname = hostname
8
+ @root_path = Config.server_path
9
+ end
10
+
11
+ def start(path)
12
+ @pid = spawn "drakov -f #{root_path}/#{path} -p #{port} --header Authorization", options
13
+ Config.active_service = { pid: @pid, path: path }
14
+ end
15
+
16
+ def stop
17
+ Process.kill 'TERM', Config.active_service[:pid]
18
+ Config.active_service = nil
19
+ end
20
+
21
+ def host
22
+ "http://localhost:#{port}"
23
+ end
24
+
25
+ def installed?
26
+ `which drakov`.length > 0
27
+ end
28
+
29
+ def install
30
+ print "installing drakov.."
31
+ pid = Process.spawn "sudo npm install -g drakov"
32
+ Process.wait pid
33
+ print "Drakov installed 🍺 "
34
+ end
35
+ private
36
+
37
+ def options
38
+ return {} if ENV["AGREEMENT_LOUD"]
39
+
40
+ { out: '/dev/null' }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,38 @@
1
+ module BlueprintAgreement
2
+ module Config
3
+ extend self
4
+ @@active_service = nil
5
+
6
+ def configure; yield self end
7
+
8
+ def port=(port)
9
+ @port = port
10
+ end
11
+
12
+ def active_service?
13
+ !!@@active_service
14
+ end
15
+
16
+ def active_service=(active_service)
17
+ @@active_service = active_service
18
+ end
19
+
20
+ def active_service
21
+ @@active_service
22
+ end
23
+
24
+ def server_path(path = './docs')
25
+ @server_path ||= path
26
+ end
27
+
28
+ def default_format
29
+ '*.apib'
30
+ end
31
+
32
+ def port
33
+ #default port so 8081
34
+ @port || '8081'
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,19 @@
1
+ module BlueprintAgreement
2
+ class EndpointNotFound < StandardError;
3
+ attr :request, :response
4
+
5
+ def initialize(request)
6
+ @request = request
7
+ @response = request
8
+ end
9
+
10
+ def message
11
+ %{
12
+ Response:
13
+ uri: #{response.uri}
14
+ code: #{response.code}
15
+ body: #{response.msg}
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Minitest
2
+ module Assertions
3
+ def assert_shall_agree_upon contract_name, response
4
+ result = BlueprintAgreement::Utils.response_parser(response.body)
5
+ api_service = BlueprintAgreement::DrakovService.new
6
+ server = BlueprintAgreement::Server.new(
7
+ api_service: api_service,
8
+ config: BlueprintAgreement::Config
9
+ )
10
+
11
+ begin
12
+ server.start(contract_name)
13
+ request = BlueprintAgreement::RequestBuilder.for(self)
14
+ requester = BlueprintAgreement::Utils::Requester.new(request, server)
15
+ expected = BlueprintAgreement::Utils.response_parser(requester.perform.body)
16
+ assert_equal expected, result
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module Minitest::Expectations
2
+ infect_an_assertion :assert_shall_agree_upon, :shall_agree_upon
3
+ end
@@ -0,0 +1,89 @@
1
+ module BlueprintAgreement
2
+ class RequestBuilder
3
+
4
+ def self.for(context)
5
+ klass = case
6
+ when rails?
7
+ RailsRequest
8
+ when rack_test?
9
+ RackTestRequest
10
+ end
11
+
12
+ klass.new(context)
13
+ end
14
+
15
+ def self.rails?
16
+ !!defined?(Rails)
17
+ end
18
+
19
+ def self.rack_test?
20
+ !!defined?(Rack::Test)
21
+ end
22
+
23
+ class RackTestRequest
24
+
25
+ def initialize(context)
26
+ @context = context
27
+ end
28
+
29
+ def body
30
+ @body ||= request.body.read
31
+ end
32
+
33
+ def content_type
34
+ request.content_type
35
+ end
36
+
37
+ def request_method
38
+ request.request_method
39
+ end
40
+
41
+ def fullpath
42
+ request.fullpath
43
+ end
44
+
45
+ def headers
46
+ @context.rack_test_session.instance_variable_get(:@headers)
47
+ end
48
+
49
+ def request
50
+ @context.last_request
51
+ end
52
+ end
53
+
54
+ class RailsRequest
55
+ HEADER_PATCH = {"CONTENT_TYPE" => "Content-Type", "HTTP_AUTHORIZATION" => "Authorization"}
56
+
57
+ def initialize(context)
58
+ @context = context
59
+ end
60
+
61
+ def body
62
+ @body ||= request.body.read
63
+ end
64
+
65
+ def content_type
66
+ request.content_type
67
+ end
68
+
69
+ def request_method
70
+ request.request_method
71
+ end
72
+
73
+ def fullpath
74
+ request.fullpath
75
+ end
76
+
77
+ def headers
78
+ HEADER_PATCH.each_with_object({}) do |header, result|
79
+ header_name, key = header
80
+ result[key] = @context.request.headers[header_name]
81
+ end.compact
82
+ end
83
+
84
+ def request
85
+ @context.request
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,31 @@
1
+ module BlueprintAgreement
2
+ class Server
3
+
4
+ def initialize(api_service:, config:)
5
+ @api_service = api_service
6
+ @config = config
7
+ end
8
+
9
+ def start(path=@config.default_format)
10
+ @api_service.install unless @api_service.installed?
11
+
12
+ if @config.active_service
13
+ restart(path) if @config.active_service[:path] != path
14
+ else
15
+ @api_service.start(path)
16
+ end
17
+ end
18
+
19
+ def restart(path)
20
+ stop && @api_service.start(path)
21
+ end
22
+
23
+ def stop
24
+ @api_service.stop
25
+ end
26
+
27
+ def host
28
+ @api_service.host
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'singleton'
2
+
3
+ module BlueprintAgreement
4
+ module Utils
5
+ class RequestLogger
6
+ include Singleton
7
+
8
+ def for(body:, headers:, path:, request_method:)
9
+ @body = body
10
+ @path = path
11
+ @request_method = request_method
12
+ @headers = headers
13
+ end
14
+
15
+ def print
16
+ header_output = @headers.to_a.map { |header| header.join("=") }.join("\n")
17
+ %{
18
+ Method: #{@request_method}
19
+ Path: #{@path}
20
+
21
+ Details
22
+
23
+ Headers:
24
+
25
+ #{ header_output }
26
+
27
+ Body:
28
+ #{@body}
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,72 @@
1
+ require 'net/http'
2
+
3
+ module BlueprintAgreement
4
+ module Utils
5
+ class Requester
6
+ REQUEST_OPTIONS = {
7
+ "GET" => Net::HTTP::Get,
8
+ "POST" => Net::HTTP::Post,
9
+ "PUT" => Net::HTTP::Put,
10
+ "DELETE" => Net::HTTP::Delete
11
+ }
12
+
13
+ def initialize(request, server)
14
+ @current_request = request
15
+ @server = server
16
+ end
17
+
18
+ def perform
19
+ begin
20
+ Net::HTTP.start(request_path.host, request_path.port) do |http|
21
+ request = REQUEST_OPTIONS[request_method].new request_path
22
+ set_form_data(request)
23
+ set_headers(request)
24
+
25
+ request_logger.for({
26
+ body: current_request.body,
27
+ headers: current_request.headers,
28
+ path: request_path,
29
+ request_method: request_method
30
+ })
31
+
32
+ http.request(request).tap do |http_request|
33
+ puts request_logger.print if ENV["AGREEMENT_LOUD"]
34
+ raise EndpointNotFound.new(http_request) if http_request.code == "404"
35
+ end
36
+ end
37
+ rescue Errno::ECONNREFUSED
38
+ sleep 1
39
+ perform
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def request_logger
46
+ Utils::RequestLogger.instance
47
+ end
48
+
49
+ def set_headers(request)
50
+ current_request.headers.each do |key, value|
51
+ request[key] = value
52
+ end
53
+ end
54
+
55
+ def set_form_data(request)
56
+ if ['POST', 'PUT'].include? request_method
57
+ request.body = current_request.body
58
+ end
59
+ end
60
+
61
+ def request_method
62
+ @request_method ||= current_request.request_method
63
+ end
64
+
65
+ def request_path
66
+ @request_path ||= URI.join(server.host, current_request.fullpath)
67
+ end
68
+
69
+ attr_reader :current_request, :server
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+
3
+ module BlueprintAgreement
4
+ module Utils
5
+ def self.response_parser(response)
6
+ JSON.pretty_generate(JSON.parse(response || ""))
7
+ rescue JSON::ParserError
8
+ return response.to_s.lstrip
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module BlueprintAgreement
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,52 @@
1
+ # gem "minitest"
2
+ require "minitest"
3
+ require "minitest"
4
+ require "minitest/spec"
5
+ require "minitest/mock"
6
+ require "blueprint_agreement/version"
7
+ require 'blueprint_agreement/config'
8
+ require 'blueprint_agreement/errors'
9
+ require 'blueprint_agreement/api_services/drakov_service'
10
+ require "blueprint_agreement/server"
11
+ require 'blueprint_agreement/request_builder'
12
+ require 'blueprint_agreement/utils/request_logger'
13
+ require 'blueprint_agreement/utils/requester'
14
+ require 'blueprint_agreement/utils/response_parser'
15
+ require 'blueprint_agreement/minitest/assertions'
16
+ require 'blueprint_agreement/minitest/expectations'
17
+
18
+ # ========================== BluePrintAgreement ==================================
19
+ # +-----------+ +-------------------+ +-----------------+
20
+ # | Minitest | | BlueprintAgreement| |Node Environment |
21
+ # +----+------+ +---------+---------+ +-----------------+
22
+ # | | |
23
+ # | shall_agree_with | |
24
+ # +------------------------> | /documentation_endpoint |
25
+ # | +------------------------------> |
26
+ # | | |
27
+ # | | |
28
+ # | | |
29
+ # | | <response> |
30
+ # | | <----------------------------+ |
31
+ # | | |
32
+ # | assert_equal | |
33
+ # | <------------------------+ |
34
+ # | | |
35
+ # | | |
36
+ # | | |
37
+ # | | |
38
+ # | | |
39
+ # | | |
40
+ # +-+-+ +--+--+ +-+-+
41
+ #
42
+ module BlueprintAgreement
43
+ Config.configure do |config|
44
+ config.port = '8082'
45
+ end
46
+ end
47
+
48
+ Minitest.after_run do
49
+ if BlueprintAgreement::Config.active_service?
50
+ Process.kill 'TERM', BlueprintAgreement::Config.active_service[:pid]
51
+ end
52
+ end
data/tasks/test.rake ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ desc "Run Test"
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/**/*_test.rb']
7
+ end
@@ -0,0 +1,31 @@
1
+ FORMAT: 1A
2
+
3
+ # The Simplest API
4
+ This is one of the simplest APIs written in the **API Blueprint**. One plain
5
+ resource combined with a method and that's it! We will explain what is going on
6
+ in the next installment -
7
+ [Resource and Actions](02.%20Resource%20and%20Actions.md).
8
+
9
+ **Note:** As we progress through the examples, do not also forget to view the
10
+ [Raw](https://raw.github.com/apiaryio/api-blueprint/master/examples/01.%20Simplest%20API.md)
11
+ code to see what is really going on in the API Blueprint, as opposed to just
12
+ seeing the output of the Github Markdown parser.
13
+
14
+ Also please keep in mind that every single example in this course is a **real
15
+ API Blueprint** and as such you can **parse** it with the
16
+ [API Blueprint parser](https://github.com/apiaryio/drafter) or one of its
17
+ [bindings](https://github.com/apiaryio/drafter#bindings).
18
+
19
+ ## API Blueprint
20
+ + [This: Raw API Blueprint](https://raw.github.com/apiaryio/api-blueprint/master/examples/01.%20Simplest%20API.md)
21
+ + [Next: Resource and Actions](02.%20Resource%20and%20Actions.md)
22
+
23
+ # GET /message
24
+ + Request 200 (application/json)
25
+ + Response 200 (application/json)
26
+
27
+ + Body
28
+
29
+ {
30
+ 'name': 'Hello World'
31
+ }
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+ require 'blueprint_agreement'
3
+
4
+ class RackTestSession
5
+ def initialize
6
+ @headers = { "Content-Type" => "application/json" }
7
+ end
8
+ end
9
+
10
+ describe "Rack Test" do
11
+ let(:body) { "\n{\n 'name': 'Hello World'\n}\n" }
12
+ let(:last_request) { RailsMocks::Request.new(fullpath: endpoint) }
13
+ let(:last_response) { RailsMocks::Response.new(body: body, request: last_request) }
14
+ let(:rack_test_session) { RackTestSession.new }
15
+
16
+ before do
17
+ module Rack; module Test; end; end
18
+ BlueprintAgreement::Config.server_path('./test/fixtures')
19
+ end
20
+
21
+ describe 'when blueprint agreement was included but never used' do
22
+ it 'returns a valid api request' do
23
+ expect(true).must_equal(true)
24
+ end
25
+ end
26
+
27
+ describe 'with valid request' do
28
+ let(:endpoint){ '/message' }
29
+ it 'returns a valid api request' do
30
+ last_response.shall_agree_upon('hello_api.md')
31
+ end
32
+ end
33
+
34
+ describe 'with invalid request' do
35
+ let(:endpoint){ '/not_valid' }
36
+ it 'returns a Not Found Route error' do
37
+ expect { last_response.shall_agree_upon('hello_api.md') }.must_raise(BlueprintAgreement::EndpointNotFound)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ require 'test_helper'
2
+ require './lib/blueprint_agreement/request_builder'
3
+
4
+ describe BlueprintAgreement::RequestBuilder do
5
+ let(:described_class) { BlueprintAgreement::RequestBuilder }
6
+
7
+ describe '.for' do
8
+ let(:context) { mock() }
9
+ let(:result) { described_class.for(context) }
10
+
11
+ describe 'when rails is defined' do
12
+ before do
13
+ described_class.stubs(:rails?).returns(true)
14
+ described_class.stubs(:rack_test?).returns(false)
15
+ end
16
+
17
+ it 'returns rails request instance' do
18
+ expect(described_class.for(context)).must_be_kind_of(described_class::RailsRequest)
19
+ end
20
+ end
21
+
22
+ describe 'when rack-test is defined' do
23
+ before do
24
+ described_class.stubs(:rails?).returns(false)
25
+ described_class.stubs(:rack_test?).returns(true)
26
+ end
27
+
28
+ it 'returns a rack test request instance' do
29
+ expect(described_class.for(context)).must_be_kind_of(described_class::RackTestRequest)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,78 @@
1
+ require 'test_helper'
2
+ require './lib/blueprint_agreement/server'
3
+
4
+ describe BlueprintAgreement::Server do
5
+ let(:api_service) { ApiService.new(config) }
6
+ let(:described_class) { BlueprintAgreement::Server }
7
+ let(:instance) { described_class.new(api_service: api_service, config: config) }
8
+ let(:config) { mock() }
9
+
10
+ describe '#start' do
11
+ let(:active_service) { { path: '*.apib' } }
12
+ let(:config) { mock(default_format: '*.apib') }
13
+
14
+ describe 'when api service is not installed' do
15
+ let(:active_service){ nil }
16
+ before do
17
+ config.unstub(:active_service)
18
+ config.stubs(:active_service).returns(active_service).once
19
+ api_service.stubs(:installed?).returns(false).once
20
+ api_service.stubs(:install).returns(true).once
21
+ api_service.stubs(:start).returns(true).once
22
+ end
23
+
24
+ it 'should install api service' do
25
+ expect(instance.start).must_equal true
26
+ end
27
+ end
28
+
29
+ describe 'when api service is already installed' do
30
+ let(:config) { mock(default_format: '*.apib') }
31
+
32
+ before do
33
+ api_service.stubs(:installed?).returns(true).once
34
+ api_service.stubs(:install).never
35
+ end
36
+
37
+ describe 'and an active service exists' do
38
+ it 'does not stop the service when it is the same path' do
39
+ config.unstub(:active_service)
40
+ config.stubs(:active_service).returns(active_service).twice
41
+ api_service.stubs(:stop).returns(true).never
42
+ api_service.stubs(:start).returns(true).never
43
+ instance.start
44
+ end
45
+
46
+ it 'restarts the service' do
47
+ config.unstub(:default_format)
48
+ config.unstub(:active_service)
49
+ config.stubs(:active_service).returns(active_service).twice
50
+ config.stubs(:default_format).never
51
+ api_service.stubs(:stop).returns(true).once
52
+ api_service.stubs(:start).returns(true).once
53
+ instance.start('differnt.apib')
54
+ end
55
+ end
56
+
57
+ describe 'without any active service' do
58
+ it 'stops the service and start again with a new active_service' do
59
+ config.stubs(:active_service).returns(nil)
60
+ api_service.stubs(:start).returns(true).once
61
+ instance.start
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+
68
+ describe '#stop' do
69
+ before do
70
+ api_service.stubs(:stop).returns(true).once
71
+ config.stubs(:active_service)
72
+ end
73
+
74
+ it 'should the api service' do
75
+ expect(instance.stop).must_equal true
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,18 @@
1
+ module RailsMocks
2
+ class Request
3
+ attr_reader :fullpath, :request_method, :content_type, :authorization, :body
4
+
5
+ def initialize(response: '', fullpath: '/message', request_method: 'GET', authorization: '', content_type: 'application/json', body: '')
6
+ @response = response
7
+ @fullpath = URI(fullpath)
8
+ @request_method = request_method
9
+ @authorization = authorization
10
+ @body = StringIO.new(body)
11
+ @content_type = content_type
12
+ end
13
+
14
+ def has_content_type?
15
+ !content_type.nil?
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ module RailsMocks
2
+ class Response
3
+ attr_reader :body, :request
4
+
5
+ def initialize(body:, request:)
6
+ @body = body
7
+ @request = request
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'bundler/setup'
3
+ Bundler.setup
4
+ require 'minitest/autorun'
5
+ require 'minitest/unit'
6
+ require 'mocha/mini_test'
7
+
8
+ ROOT_PATH = File.dirname(__FILE__)
9
+ Dir[File.join(ROOT_PATH, "support/**/*.rb")].each { |f| require f }
10
+
11
+ class ApiService
12
+
13
+ def initialize(config)
14
+ @config = config
15
+ end
16
+
17
+ def start; end
18
+ def installed?; end
19
+ def install; end
20
+ def stop; end
21
+ def options; end
22
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blueprint_agreement
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Charly Palencia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '9.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '9.0'
83
+ description: A Minitest API Documentation Matcher , based on ApiBluePrint schema.
84
+ email:
85
+ - charly.palencia@koombea.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".ruby-version"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - LICENSE
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - blueprint_agreement.gemspec
99
+ - lib/blueprint_agreement.rb
100
+ - lib/blueprint_agreement/api_services/drakov_service.rb
101
+ - lib/blueprint_agreement/config.rb
102
+ - lib/blueprint_agreement/errors.rb
103
+ - lib/blueprint_agreement/minitest/assertions.rb
104
+ - lib/blueprint_agreement/minitest/expectations.rb
105
+ - lib/blueprint_agreement/request_builder.rb
106
+ - lib/blueprint_agreement/server.rb
107
+ - lib/blueprint_agreement/utils/request_logger.rb
108
+ - lib/blueprint_agreement/utils/requester.rb
109
+ - lib/blueprint_agreement/utils/response_parser.rb
110
+ - lib/blueprint_agreement/version.rb
111
+ - tasks/test.rake
112
+ - test/fixtures/hello_api.md
113
+ - test/integration/simple_api_test.rb
114
+ - test/request_builder_test.rb
115
+ - test/server_test.rb
116
+ - test/support/rails_mocks/request.rb
117
+ - test/support/rails_mocks/response.rb
118
+ - test/test_helper.rb
119
+ homepage: http://www.chalien.com
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.5.1
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: A Minitest API Documentation Matcher , based on ApiBluePrint schema.
143
+ test_files:
144
+ - test/fixtures/hello_api.md
145
+ - test/integration/simple_api_test.rb
146
+ - test/request_builder_test.rb
147
+ - test/server_test.rb
148
+ - test/support/rails_mocks/request.rb
149
+ - test/support/rails_mocks/response.rb
150
+ - test/test_helper.rb