kanpachi 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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +13 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +131 -0
- data/Rakefile +10 -0
- data/bin/kanpachi +17 -0
- data/examples/twitter.rb +122 -0
- data/kanpachi.gemspec +45 -0
- data/lib/base_hash.rb +41 -0
- data/lib/kanpachi/api.rb +22 -0
- data/lib/kanpachi/api_list.rb +61 -0
- data/lib/kanpachi/cli/doc.rb +62 -0
- data/lib/kanpachi/cli.rb +32 -0
- data/lib/kanpachi/commands/new.rb +26 -0
- data/lib/kanpachi/documentation/config.rb +84 -0
- data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.svg +228 -0
- data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/kanpachi/documentation/source/images/background.png +0 -0
- data/lib/kanpachi/documentation/source/images/middleman.png +0 -0
- data/lib/kanpachi/documentation/source/index.html.slim +25 -0
- data/lib/kanpachi/documentation/source/javascripts/all.js +1 -0
- data/lib/kanpachi/documentation/source/javascripts/bootstrap.js +1999 -0
- data/lib/kanpachi/documentation/source/javascripts/bootstrap.min.js +6 -0
- data/lib/kanpachi/documentation/source/javascripts/html5shiv.js +9 -0
- data/lib/kanpachi/documentation/source/javascripts/jquery-1.10.2.min.js +6 -0
- data/lib/kanpachi/documentation/source/javascripts/respond.min.js +7 -0
- data/lib/kanpachi/documentation/source/layouts/layout.slim +55 -0
- data/lib/kanpachi/documentation/source/resource.html.slim +61 -0
- data/lib/kanpachi/documentation/source/stylesheets/bootstrap-theme.css +384 -0
- data/lib/kanpachi/documentation/source/stylesheets/bootstrap-theme.min.css +1 -0
- data/lib/kanpachi/documentation/source/stylesheets/bootstrap.css +6805 -0
- data/lib/kanpachi/documentation/source/stylesheets/bootstrap.min.css +9 -0
- data/lib/kanpachi/documentation/source/stylesheets/jumbotron.css +5 -0
- data/lib/kanpachi/dsl/api.rb +90 -0
- data/lib/kanpachi/dsl/error.rb +37 -0
- data/lib/kanpachi/dsl/resource.rb +110 -0
- data/lib/kanpachi/dsl/response.rb +21 -0
- data/lib/kanpachi/dsl/section.rb +29 -0
- data/lib/kanpachi/dsl.rb +24 -0
- data/lib/kanpachi/error.rb +14 -0
- data/lib/kanpachi/error_list.rb +51 -0
- data/lib/kanpachi/markdown.rb +11 -0
- data/lib/kanpachi/resource/params.rb +9 -0
- data/lib/kanpachi/resource.rb +56 -0
- data/lib/kanpachi/resource_list.rb +71 -0
- data/lib/kanpachi/response.rb +68 -0
- data/lib/kanpachi/response_list.rb +51 -0
- data/lib/kanpachi/section.rb +15 -0
- data/lib/kanpachi/section_list.rb +46 -0
- data/lib/kanpachi/templates/.gitignore +19 -0
- data/lib/kanpachi/templates/Gemfile +4 -0
- data/lib/kanpachi/templates/api/api.rb +17 -0
- data/lib/kanpachi/templates/api/errors.rb +13 -0
- data/lib/kanpachi/templates/api/posts.rb +32 -0
- data/lib/kanpachi/templates/api/users.rb +38 -0
- data/lib/kanpachi/version.rb +3 -0
- data/lib/kanpachi.rb +7 -0
- data/spec/api_list_spec.rb +55 -0
- data/spec/api_spec.rb +56 -0
- data/spec/dsl/api_spec.rb +74 -0
- data/spec/dsl/error_spec.rb +38 -0
- data/spec/dsl/resource_spec.rb +77 -0
- data/spec/dsl/response_spec.rb +31 -0
- data/spec/dsl/section_spec.rb +49 -0
- data/spec/dsl_spec.rb +46 -0
- data/spec/error_list_spec.rb +43 -0
- data/spec/error_spec.rb +34 -0
- data/spec/full_api_spec.rb +130 -0
- data/spec/markdown_spec.rb +12 -0
- data/spec/resource/params_spec.rb +11 -0
- data/spec/resource_list_spec.rb +53 -0
- data/spec/resource_spec.rb +144 -0
- data/spec/response_spec.rb +57 -0
- data/spec/section_list_spec.rb +39 -0
- data/spec/section_spec.rb +20 -0
- data/spec/spec_helper.rb +4 -0
- metadata +384 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'kanpachi/resource/params'
|
3
|
+
require 'kanpachi/response_list'
|
4
|
+
|
5
|
+
module Kanpachi
|
6
|
+
# The Resource class
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
class Resource
|
10
|
+
attr_reader :http_verb
|
11
|
+
attr_reader :url
|
12
|
+
attr_reader :formats
|
13
|
+
attr_reader :versions
|
14
|
+
attr_reader :responses
|
15
|
+
attr_accessor :params
|
16
|
+
attr_accessor :name
|
17
|
+
attr_accessor :description
|
18
|
+
attr_accessor :priority
|
19
|
+
attr_accessor :ssl
|
20
|
+
attr_accessor :authentication
|
21
|
+
|
22
|
+
# Resource constructor
|
23
|
+
#
|
24
|
+
# @param http_berb [Symbol] Resource http verb.
|
25
|
+
# @param url [String] Resource's url. The url will automatically be prepended a slash if it doesn't already contain one.
|
26
|
+
# @api public
|
27
|
+
def initialize(http_verb, url)
|
28
|
+
@url = url.start_with?('/') ? url : "/#{url}"
|
29
|
+
@http_verb = http_verb
|
30
|
+
@formats = Set.new
|
31
|
+
@versions = Set.new
|
32
|
+
@priority = 50
|
33
|
+
@ssl = false
|
34
|
+
@authentication = false
|
35
|
+
@params = Class.new(Params)
|
36
|
+
@responses = Kanpachi::ResponseList.new
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns true if the resource has defined any params.
|
40
|
+
#
|
41
|
+
# @return [Boolean]
|
42
|
+
def params?
|
43
|
+
!(params.input_filters.required_inputs.empty? && params.input_filters.optional_inputs.empty?)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Compare two resources using the priority
|
47
|
+
def <=> (other)
|
48
|
+
priority <=> other.priority
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the http verb concatenated with the url
|
52
|
+
def route
|
53
|
+
"#{@http_verb.to_s.upcase} #{@url}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Kanpachi
|
2
|
+
# Class to keep track of all defined resources
|
3
|
+
#
|
4
|
+
# @api public
|
5
|
+
class ResourceList
|
6
|
+
class UnknownResource < StandardError; end
|
7
|
+
class DuplicateResource < StandardError; end
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@list = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns a hash of resources
|
14
|
+
#
|
15
|
+
# @return [Hash<Kanpachi::Resource>] All the added resources.
|
16
|
+
# @api public
|
17
|
+
def to_hash
|
18
|
+
@list
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns an array of resources
|
22
|
+
#
|
23
|
+
# @return [Array<Kanpachi::Resource>] List of added resources.
|
24
|
+
# @api public
|
25
|
+
def all
|
26
|
+
@list.values
|
27
|
+
end
|
28
|
+
|
29
|
+
# Add a resource to the list
|
30
|
+
#
|
31
|
+
# @param [Kanpachi::Resource] The resource to add.
|
32
|
+
# @return [Hash<Kanpachi::Resource>] All the added resources.
|
33
|
+
# @raise DuplicateResource If a resource is being duplicated.
|
34
|
+
# @api public
|
35
|
+
def add(resource)
|
36
|
+
if @list.key? resource.route
|
37
|
+
raise DuplicateResource, "A resource accessible via #{resource.http_verb} #{resource.url} already exists"
|
38
|
+
end
|
39
|
+
@list[resource.route] = resource
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a resource based on its name
|
43
|
+
#
|
44
|
+
# @param [String] name The name of the resource you are looking for.
|
45
|
+
# @raise [UnknownResource] if a resource with the passed name isn't found.
|
46
|
+
# @return [Kanpachi::Resource] The found resource.
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
def named(name)
|
50
|
+
resource = all.detect { |resource| resource.name == name }
|
51
|
+
if resource.nil?
|
52
|
+
raise UnknownResource, "Resource named #{name} doesn't exist"
|
53
|
+
else
|
54
|
+
resource
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns a resource based on its verb and url
|
59
|
+
#
|
60
|
+
# @param [String] verb The request method (GET, POST, PUT, DELETE)
|
61
|
+
# @param [String] url The url of the resource you are looking for.
|
62
|
+
# @return [Nil, Kanpachi::Resource] The found resource.
|
63
|
+
#
|
64
|
+
# @api public
|
65
|
+
def find(verb, url)
|
66
|
+
http_verb = verb.to_s.upcase
|
67
|
+
route = "#{http_verb} #{url}"
|
68
|
+
@list[route]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'roar/representer'
|
2
|
+
require 'roar/representer/feature/hypermedia'
|
3
|
+
require 'representable/json/collection'
|
4
|
+
require 'representable/json/hash'
|
5
|
+
|
6
|
+
module Kanpachi
|
7
|
+
class Response
|
8
|
+
attr_reader :name
|
9
|
+
attr_reader :headers
|
10
|
+
attr_accessor :status
|
11
|
+
attr_accessor :representation
|
12
|
+
|
13
|
+
def initialize(name)
|
14
|
+
@name = name
|
15
|
+
@status = 200
|
16
|
+
@headers = {}
|
17
|
+
@representation = Module.new { include Representation }
|
18
|
+
end
|
19
|
+
|
20
|
+
module Representation
|
21
|
+
def self.included(base)
|
22
|
+
base.class_eval do
|
23
|
+
include Roar::Representer
|
24
|
+
include Roar::Representer::Feature::Hypermedia
|
25
|
+
|
26
|
+
def self.example
|
27
|
+
example = Hash.new
|
28
|
+
self.properties.each do |key, value|
|
29
|
+
if value[:hash]
|
30
|
+
example[key] = value[:extend] ? value[:extend].example : (value[:example] || Hash.new)
|
31
|
+
elsif value[:collection]
|
32
|
+
example[key] = value[:extend] ? [value[:extend].example] : (value[:example] || Array.new)
|
33
|
+
elsif value[:type] == Integer
|
34
|
+
example[key] = value[:example] || 1
|
35
|
+
elsif value[:type] == String
|
36
|
+
example[key] = value[:example] || 'String'
|
37
|
+
elsif !!value[:type] == value[:type]
|
38
|
+
example[key] = value[:example] || true
|
39
|
+
elsif value[:type] == DateTime
|
40
|
+
example[key] = value[:example] || "2013-01-01T19:06:43Z"
|
41
|
+
else
|
42
|
+
example[key] = value[:example] || 'String'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
if self.included_modules.include?(::Representable::JSON::Collection)
|
46
|
+
example = [example]
|
47
|
+
elsif self.included_modules.include?(::Representable::JSON::Hash)
|
48
|
+
example = example['_self'] || Hash.new
|
49
|
+
end
|
50
|
+
example
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.properties
|
54
|
+
hash = Hash.new
|
55
|
+
representable_attrs.each do |definition|
|
56
|
+
if definition.options[:extend]
|
57
|
+
hash[definition.name] = definition.options.merge(definition.options[:extend].properties)
|
58
|
+
else
|
59
|
+
hash[definition.name] = definition.options
|
60
|
+
end
|
61
|
+
end
|
62
|
+
hash
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Kanpachi
|
2
|
+
# Class to keep track of all defined responses
|
3
|
+
#
|
4
|
+
# @api public
|
5
|
+
class ResponseList
|
6
|
+
class DuplicateResponse < StandardError; end
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@list = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns a hash of responses
|
13
|
+
#
|
14
|
+
# @return [Hash<Kanpachi::Response>] All the added responses.
|
15
|
+
# @api public
|
16
|
+
def to_hash
|
17
|
+
@list
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns an array of responses
|
21
|
+
#
|
22
|
+
# @return [Array<Kanpachi::Response>] List of added responses.
|
23
|
+
# @api public
|
24
|
+
def all
|
25
|
+
@list.values
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add a response to the list
|
29
|
+
#
|
30
|
+
# @param [Kanpachi::Response] response The response to add.
|
31
|
+
# @return [Hash<Kanpachi::Response>] All the added responses.
|
32
|
+
# @raise DuplicateResponse If a response is being duplicated.
|
33
|
+
# @api public
|
34
|
+
def add(response)
|
35
|
+
if @list.key? response.name
|
36
|
+
raise DuplicateResponse, "A response named #{response.name} already exists"
|
37
|
+
end
|
38
|
+
@list[response.name] = response
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a response based on its verb and url
|
42
|
+
#
|
43
|
+
# @param [String] name The name of the response you are looking for.
|
44
|
+
# @return [Nil, Kanpachi::Response] The found response.
|
45
|
+
#
|
46
|
+
# @api public
|
47
|
+
def find(name)
|
48
|
+
@list[name]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Kanpachi
|
2
|
+
# Class to keep track of all defined sections
|
3
|
+
#
|
4
|
+
# @api public
|
5
|
+
class SectionList
|
6
|
+
def initialize
|
7
|
+
@list = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns a hash of sections
|
11
|
+
#
|
12
|
+
# @return [Hash<Kanpachi::Section>] All the added sections.
|
13
|
+
# @api public
|
14
|
+
def to_hash
|
15
|
+
@list
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns an array of sections
|
19
|
+
#
|
20
|
+
# @return [Array<Kanpachi::Section>] List of added sections.
|
21
|
+
# @api public
|
22
|
+
def all
|
23
|
+
@list.values
|
24
|
+
end
|
25
|
+
|
26
|
+
# Add a section to the list
|
27
|
+
#
|
28
|
+
# @param [Kanpachi::Section] section The section to add.
|
29
|
+
# @return [Hash<Kanpachi::Section>] All the added sections.
|
30
|
+
# @api public
|
31
|
+
def add(section)
|
32
|
+
@list[section.name] = section
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a section based on its verb and url
|
36
|
+
#
|
37
|
+
# @param [String] verb The request method (GET, POST, PUT, DELETE)
|
38
|
+
# @param [String] url The url of the section you are looking for.
|
39
|
+
# @return [Nil, Kanpachi::Section] The found section.
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def find(name)
|
43
|
+
@list[name]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
api 'MyAPI' do
|
2
|
+
title 'REST API v1.0 Resources'
|
3
|
+
description 'This describes the resources that make up the official API'
|
4
|
+
host 'api.example.com'
|
5
|
+
|
6
|
+
section 'Users' do
|
7
|
+
description 'Users are users of the system.'
|
8
|
+
end
|
9
|
+
|
10
|
+
section 'Posts' do
|
11
|
+
description 'Posts are blog posts from users.'
|
12
|
+
end
|
13
|
+
|
14
|
+
section 'Comments' do
|
15
|
+
description 'Comments are made by users on blog posts.'
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
api 'MyAPI' do
|
2
|
+
error :malformed_params do
|
3
|
+
description 'Sending invalid JSON will result in a 400 Bad Request response.'
|
4
|
+
|
5
|
+
response do
|
6
|
+
status 400
|
7
|
+
header 'Content-Type', 'application/json'
|
8
|
+
representation do
|
9
|
+
property :message, type: String
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'representable/json/collection'
|
2
|
+
|
3
|
+
api 'MyAPI' do
|
4
|
+
section 'Posts' do
|
5
|
+
resource :get, '/posts' do
|
6
|
+
name 'List Posts'
|
7
|
+
description <<-TEXT
|
8
|
+
Return a collection of __blog posts__. Sort order defaults to _most recently published_.
|
9
|
+
TEXT
|
10
|
+
versions '1.0'
|
11
|
+
ssl true
|
12
|
+
formats :json
|
13
|
+
|
14
|
+
params do
|
15
|
+
optional do
|
16
|
+
integer :size, max: 100, doc: 'The number of results to return. (max: 100)', example: 10
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
response do
|
21
|
+
status 200
|
22
|
+
header 'Content-Type', 'application/json'
|
23
|
+
representation do
|
24
|
+
include Representable::JSON::Collection
|
25
|
+
property :title, type: String, doc: 'Title of the post', example: 'APIs Run Amok!'
|
26
|
+
property :body, type: String, doc: 'The Body of the post ', example: 'I love me some API!'
|
27
|
+
property :created_at, type: DateTime, doc: 'When the post was created.'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
api 'MyAPI' do
|
2
|
+
section 'Users' do
|
3
|
+
resource :post, '/users' do
|
4
|
+
name 'Create a user'
|
5
|
+
description <<-TEXT
|
6
|
+
__Creates a user__. `User`'s must provide a valid email address. Upon registration,
|
7
|
+
an activation email will be sent to the user.
|
8
|
+
TEXT
|
9
|
+
versions '1.0'
|
10
|
+
ssl true
|
11
|
+
formats :json
|
12
|
+
|
13
|
+
params do
|
14
|
+
required do
|
15
|
+
string :email, doc: 'Email address', example: 'user@example.com'
|
16
|
+
string :full_name, doc: 'Full name', example: 'Jack Chu'
|
17
|
+
string :password, min_length: 8, doc: 'The password must be 8 characters minumum', example: 'notPassword'
|
18
|
+
string :password_confirmation, min_length: 8, doc: 'Password (confirm)'
|
19
|
+
integer :age, doc: 'Age', example: 21
|
20
|
+
end
|
21
|
+
|
22
|
+
optional do
|
23
|
+
boolean :newsletter, doc: 'Do you want our weekly newsletter?', default: false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
response do
|
28
|
+
status 201
|
29
|
+
header 'Content-Type', 'application/json'
|
30
|
+
representation do
|
31
|
+
property :message, type: String, doc: 'Thank you message for the user.', example: 'Thanks for registering!'
|
32
|
+
collection :roles, doc: 'The authorization roles this user has.', example: ['member', 'superuser']
|
33
|
+
hash :preferences, doc: 'The preferences for this user.', example: {remember_me: true, newsletter: false}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/kanpachi.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Kanpachi::APIList do
|
4
|
+
before do
|
5
|
+
Kanpachi::APIList.clear
|
6
|
+
end
|
7
|
+
|
8
|
+
subject do
|
9
|
+
Kanpachi::APIList
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'initializes empty' do
|
13
|
+
subject.all.must_be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'Populated API' do
|
17
|
+
let(:myapp_api) do
|
18
|
+
Kanpachi::API.new('MyApp')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns a hash of the internal list, with API names as the key and a Section object as the value' do
|
22
|
+
Kanpachi::APIList.add(myapp_api)
|
23
|
+
subject.to_hash.keys.must_include 'MyApp'
|
24
|
+
subject.to_hash['MyApp'].must_equal myapp_api
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns an array of Section objects' do
|
28
|
+
Kanpachi::APIList.add(myapp_api)
|
29
|
+
subject.all.must_include myapp_api
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'adds a API' do
|
33
|
+
subject.add(myapp_api)
|
34
|
+
subject.all.must_include myapp_api
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'deletes a API' do
|
38
|
+
subject.add(myapp_api)
|
39
|
+
subject.delete(myapp_api.name)
|
40
|
+
subject.all.wont_include myapp_api
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'finds a API by name' do
|
44
|
+
Kanpachi::APIList.add(myapp_api)
|
45
|
+
subject.find('MyApp').must_equal myapp_api
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'clears all APIs' do
|
50
|
+
myapp_api = Kanpachi::API.new('MyApp')
|
51
|
+
Kanpachi::APIList.add(myapp_api)
|
52
|
+
subject.clear
|
53
|
+
subject.all.size.must_equal 0
|
54
|
+
end
|
55
|
+
end
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Kanpachi::API do
|
4
|
+
subject do
|
5
|
+
Kanpachi::API.new('MockApi')
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns the API name' do
|
9
|
+
subject.name.must_equal 'MockApi'
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'initializes resources as a Kanpachi::ResourceList' do
|
13
|
+
subject.resources.class.must_equal Kanpachi::ResourceList
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'initializes errors as a Kanpachi::ErrorList' do
|
17
|
+
subject.errors.class.must_equal Kanpachi::ErrorList
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'initializes sections as a Kanpachi::SectionList' do
|
21
|
+
subject.sections.class.must_equal Kanpachi::SectionList
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'has a title' do
|
25
|
+
subject.title = 'The Mock API!'
|
26
|
+
subject.title.must_equal 'The Mock API!'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has a description' do
|
30
|
+
subject.description = 'API for testing'
|
31
|
+
subject.description.must_equal 'API for testing'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'has a host' do
|
35
|
+
subject.description = 'API for testing'
|
36
|
+
subject.description.must_equal 'API for testing'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'has sections' do
|
40
|
+
section = Kanpachi::Section.new('Stuff')
|
41
|
+
subject.sections.add(section)
|
42
|
+
subject.sections.find('Stuff').must_equal section
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has errors' do
|
46
|
+
error = Kanpachi::Error.new(:not_found)
|
47
|
+
subject.errors.add(error)
|
48
|
+
subject.errors.find(:not_found).must_equal error
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'has resources' do
|
52
|
+
resource = Kanpachi::Resource.new(:post, '/posts')
|
53
|
+
subject.resources.add(resource)
|
54
|
+
subject.resources.find(:post, '/posts').must_equal resource
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Kanpachi::DSL::API do
|
4
|
+
subject do
|
5
|
+
Kanpachi::DSL::API.new(my_api)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:my_api) do
|
9
|
+
extend Kanpachi::DSL
|
10
|
+
api 'MyApp' do
|
11
|
+
title 'My App'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sets the title' do
|
16
|
+
subject.title 'My Little API'
|
17
|
+
my_api.title.must_equal 'My Little API'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'sets the description' do
|
21
|
+
subject.description 'Just for testing'
|
22
|
+
my_api.description.must_equal 'Just for testing'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'sets the host' do
|
26
|
+
subject.host 'api.localhost.dev'
|
27
|
+
my_api.host.must_equal 'api.localhost.dev'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'adds a new error to the error list' do
|
31
|
+
error = subject.error :not_authorized
|
32
|
+
my_api.errors.find(:not_authorized).must_equal error
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'raises a Kanpachi::ErrorList::DuplicateError if error name already exists' do
|
36
|
+
subject.error :not_found
|
37
|
+
proc do
|
38
|
+
subject.error :not_found do
|
39
|
+
response do
|
40
|
+
status 400
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end.must_raise Kanpachi::ErrorList::DuplicateError
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'adds a new section to the section list' do
|
47
|
+
subject.section 'Posts'
|
48
|
+
my_api.sections.find('Posts').name.must_equal 'Posts'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'reopens a section with the same name in the section list' do
|
52
|
+
subject.section 'Users'
|
53
|
+
section = subject.section 'Users' do
|
54
|
+
description 'Users Section'
|
55
|
+
end
|
56
|
+
my_api.sections.find('Users').must_equal section
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'adds a new resource to the resource list' do
|
60
|
+
resource = subject.resource :get, '/posts'
|
61
|
+
my_api.resources.find(:get, '/posts').must_equal resource
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'raises a Kanpachi::ResourceList::DuplicateResource if resource route already exists' do
|
65
|
+
subject.resource :get, '/users'
|
66
|
+
proc do
|
67
|
+
subject.resource :get, '/users' do
|
68
|
+
response do
|
69
|
+
status 400
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end.must_raise Kanpachi::ResourceList::DuplicateResource
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe Kanpachi::DSL::Error do
|
4
|
+
before do
|
5
|
+
Kanpachi::APIList.clear
|
6
|
+
end
|
7
|
+
|
8
|
+
subject do
|
9
|
+
Kanpachi::DSL::Error.new(not_found_error, api_dsl)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:not_found_error) do
|
13
|
+
Kanpachi::Error.new(:not_found_error)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:api_dsl) do
|
17
|
+
Kanpachi::DSL::API.new(my_api)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:my_api) do
|
21
|
+
extend Kanpachi::DSL
|
22
|
+
api 'MyApp' do
|
23
|
+
title 'My App'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'sets the description' do
|
28
|
+
subject.description 'Just for testing'
|
29
|
+
not_found_error.description.must_equal 'Just for testing'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'sets the response' do
|
33
|
+
subject.response do
|
34
|
+
status 201
|
35
|
+
end
|
36
|
+
not_found_error.response.status.must_equal 201
|
37
|
+
end
|
38
|
+
end
|