apipie-rails 0.0.24 → 0.1.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.
- data/.gitignore +1 -1
- data/.travis.yml +6 -0
- data/CHANGELOG.md +97 -0
- data/Gemfile +1 -1
- data/Gemfile.rails30 +5 -0
- data/Gemfile.rails32 +5 -0
- data/Gemfile.rails40 +5 -0
- data/Gemfile.rails41 +5 -0
- data/README.rst +126 -11
- data/apipie-rails.gemspec +1 -1
- data/app/controllers/apipie/apipies_controller.rb +3 -0
- data/app/helpers/apipie_helper.rb +9 -0
- data/app/views/apipie/apipies/_metadata.erb +1 -0
- data/app/views/apipie/apipies/_method_detail.erb +46 -0
- data/app/views/apipie/apipies/_params.html.erb +12 -0
- data/app/views/apipie/apipies/_params_plain.html.erb +4 -0
- data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
- data/app/views/apipie/apipies/method.html.erb +1 -37
- data/app/views/apipie/apipies/plain.html.erb +1 -0
- data/app/views/apipie/apipies/resource.html.erb +6 -37
- data/app/views/apipie/apipies/static.html.erb +1 -0
- data/lib/apipie/application.rb +16 -2
- data/lib/apipie/configuration.rb +8 -2
- data/lib/apipie/dsl_definition.rb +25 -6
- data/lib/apipie/error_description.rb +22 -10
- data/lib/apipie/extractor.rb +2 -1
- data/lib/apipie/extractor/writer.rb +8 -6
- data/lib/apipie/method_description.rb +7 -4
- data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
- data/lib/apipie/param_description.rb +25 -4
- data/lib/apipie/resource_description.rb +8 -4
- data/lib/apipie/routing.rb +1 -0
- data/lib/apipie/validator.rb +71 -3
- data/lib/apipie/version.rb +1 -1
- data/lib/tasks/apipie.rake +26 -5
- data/spec/controllers/apipies_controller_spec.rb +2 -0
- data/spec/controllers/concerns_controller_spec.rb +1 -1
- data/spec/controllers/users_controller_spec.rb +130 -19
- data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +1 -0
- data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +22 -20
- data/spec/dummy/app/controllers/concerns/sample_controller.rb +32 -30
- data/spec/dummy/app/controllers/users_controller.rb +18 -5
- data/spec/lib/method_description_spec.rb +22 -0
- data/spec/lib/param_description_spec.rb +77 -0
- data/spec/lib/rake_spec.rb +68 -0
- data/spec/lib/resource_description_spec.rb +18 -0
- data/spec/lib/validator_spec.rb +9 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/support/rake.rb +21 -0
- metadata +20 -7
- data/CHANGELOG +0 -72
@@ -1,29 +1,31 @@
|
|
1
1
|
module Api
|
2
2
|
module V2
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Nested
|
4
|
+
class ArchitecturesController < V2::BaseController
|
5
|
+
resource_description { name 'Architectures' }
|
6
|
+
api :GET, "/nested/architectures/", "List all nested architectures."
|
7
|
+
def index
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
api :GET, "/nested/architectures/:id/", "Show a nested architecture."
|
11
|
+
def show
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
api :POST, "/nested/architectures/", "Create a nested architecture."
|
15
|
+
param_group :arch, Api::V1::ArchitecturesController
|
16
|
+
def create
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
api :PUT, "/nested/architectures/:id/", "Update a nested architecture."
|
20
|
+
param :architecture, Hash, :required => true do
|
21
|
+
param :name, String
|
22
|
+
end
|
23
|
+
def update
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
api :DELETE, "/architecturess/:id/", "Delete a nested architecture."
|
27
|
+
def destroy
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
@@ -1,39 +1,41 @@
|
|
1
|
-
module Concerns
|
2
|
-
|
1
|
+
module Concerns
|
2
|
+
module SampleController
|
3
|
+
extend Apipie::DSL::Concern
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
api :GET, '/:controller_path'
|
6
|
+
def index
|
7
|
+
render :text => "OK #{params.inspect}"
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
api :GET, '/:resource_id/:id'
|
11
|
+
param :id, String
|
12
|
+
def show
|
13
|
+
render :text => "OK #{params.inspect}"
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def_param_group :concern do
|
17
|
+
param :concern, Hash, :required => true, :action_aware => true do
|
18
|
+
param :name, String, "Name of a :concern"
|
19
|
+
param :concern_type, String
|
20
|
+
end
|
19
21
|
end
|
20
|
-
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
api :POST, '/:resource_id', "Create a :concern"
|
24
|
+
param_group :concern
|
25
|
+
def create
|
26
|
+
render :text => "OK #{params.inspect}"
|
27
|
+
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
api :PUT, '/:resource_id/:id'
|
30
|
+
param :id, String
|
31
|
+
param_group :concern
|
32
|
+
def update
|
33
|
+
render :text => "OK #{params.inspect}"
|
34
|
+
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
api :GET, '/:resource_id/:custom_subst'
|
37
|
+
def custom
|
38
|
+
render :text => "OK #{params.inspect}"
|
39
|
+
end
|
38
40
|
end
|
39
41
|
end
|
@@ -5,13 +5,16 @@ class UsersController < ApplicationController
|
|
5
5
|
path '/users'
|
6
6
|
formats ['json']
|
7
7
|
param :id, Fixnum, :desc => "User ID", :required => false
|
8
|
-
param :
|
9
|
-
param :
|
10
|
-
|
8
|
+
param :legacy_param, Hash, :desc => 'Deprecated parameter not documented', :show => false, :required => false do
|
9
|
+
param :resource_param, Hash, :desc => 'Param description for all methods' do
|
10
|
+
param :ausername, String, :desc => "Username for login", :required => true
|
11
|
+
param :apassword, String, :desc => "Password for login", :required => true
|
12
|
+
end
|
11
13
|
end
|
12
14
|
api_version "development"
|
13
|
-
error 404, "Missing"
|
15
|
+
error 404, "Missing", :meta => {:some => "metadata"}
|
14
16
|
error 500, "Server crashed for some <%= reason %>"
|
17
|
+
meta :new_style => true, :author => { :name => 'John', :surname => 'Doe' }
|
15
18
|
description <<-EOS
|
16
19
|
== Long description
|
17
20
|
|
@@ -177,6 +180,13 @@ class UsersController < ApplicationController
|
|
177
180
|
val == "param value" ? true : "The only good value is 'param value'."
|
178
181
|
}, :desc => "proc validator"
|
179
182
|
param :briefer_dsl, String, "You dont need :desc => from now"
|
183
|
+
param :meta_param, String, :desc => "A parameter with some additional metadata", :meta => [:some, :more, :info]
|
184
|
+
meta :success_message => "Some message"
|
185
|
+
param :hash_param, Hash, :desc => "Hash param" do
|
186
|
+
param :dummy_hash, Hash do
|
187
|
+
param :dummy_2, String, :required => true
|
188
|
+
end
|
189
|
+
end
|
180
190
|
def show
|
181
191
|
unless params[:session] == "secret_hash"
|
182
192
|
render :text => "Not authorized", :status => 401
|
@@ -212,8 +222,11 @@ class UsersController < ApplicationController
|
|
212
222
|
render :text => "OK #{params.inspect}"
|
213
223
|
end
|
214
224
|
|
215
|
-
api :PUT, "/users/:id", "
|
225
|
+
api :PUT, "/users/:id", "Update an user"
|
216
226
|
param_group :user
|
227
|
+
param :comments, Array do
|
228
|
+
param :comment, String
|
229
|
+
end
|
217
230
|
def update
|
218
231
|
render :text => "OK #{params.inspect}"
|
219
232
|
end
|
@@ -4,6 +4,28 @@ describe Apipie::MethodDescription do
|
|
4
4
|
|
5
5
|
let(:dsl_data) { ActionController::Base.send(:_apipie_dsl_data_init) }
|
6
6
|
|
7
|
+
describe "metadata" do
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
@resource = Apipie::ResourceDescription.new(ApplicationController, "dummy")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return nil when no metadata is provided" do
|
14
|
+
method = Apipie::MethodDescription.new(:a, @resource, dsl_data)
|
15
|
+
method.to_json[:metadata].should == nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return the metadata" do
|
19
|
+
meta = {
|
20
|
+
:lenght => 32,
|
21
|
+
:weight => '830g'
|
22
|
+
}
|
23
|
+
method = Apipie::MethodDescription.new(:a, @resource, dsl_data.update(:meta => meta))
|
24
|
+
method.to_json[:metadata].should == meta
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
7
29
|
describe "params descriptions" do
|
8
30
|
|
9
31
|
before(:each) do
|
@@ -12,6 +12,73 @@ describe Apipie::ParamDescription do
|
|
12
12
|
Apipie::MethodDescription.new(:show, resource_desc, dsl_data)
|
13
13
|
end
|
14
14
|
|
15
|
+
describe "metadata" do
|
16
|
+
|
17
|
+
it "should return nil when no metadata is provided" do
|
18
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String)
|
19
|
+
param.to_json[:metadata].should == nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return the metadata" do
|
23
|
+
meta = {
|
24
|
+
:lenght => 32,
|
25
|
+
:weight => '830g'
|
26
|
+
}
|
27
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String, :meta => meta)
|
28
|
+
param.to_json[:metadata].should == meta
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "show option" do
|
34
|
+
|
35
|
+
it "should return true when show option is not provided" do
|
36
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String)
|
37
|
+
param.to_json[:show].should == true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return the show option" do
|
41
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String, :show => true)
|
42
|
+
param.to_json[:show].should == true
|
43
|
+
|
44
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String, :show => false)
|
45
|
+
param.to_json[:show].should == false
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "full_name" do
|
51
|
+
context "with no nested parameters" do
|
52
|
+
|
53
|
+
it "should return name" do
|
54
|
+
param = Apipie::ParamDescription.new(method_desc, :some_param, String)
|
55
|
+
param.to_json[:full_name].should == 'some_param'
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with nested parameters" do
|
61
|
+
|
62
|
+
it "should return the parameter's name nested in the parents name" do
|
63
|
+
parent_param = Apipie::ParamDescription.new(method_desc, :parent, String)
|
64
|
+
nested_param = Apipie::ParamDescription.new(method_desc, :nested, String, :parent => parent_param)
|
65
|
+
|
66
|
+
nested_param.to_json[:full_name].should == 'parent[nested]'
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with the parent parameter set to not show" do
|
70
|
+
|
71
|
+
it "should return just the parameter's name" do
|
72
|
+
parent_param = Apipie::ParamDescription.new(method_desc, :parent, String, :show => false)
|
73
|
+
nested_param = Apipie::ParamDescription.new(method_desc, :nested, String, :parent => parent_param)
|
74
|
+
|
75
|
+
nested_param.to_json[:full_name].should == 'nested'
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
15
82
|
describe "validator selection" do
|
16
83
|
|
17
84
|
it "should allow nil validator" do
|
@@ -171,4 +238,14 @@ describe Apipie::ParamDescription do
|
|
171
238
|
end
|
172
239
|
end
|
173
240
|
end
|
241
|
+
|
242
|
+
|
243
|
+
describe "Array with classes" do
|
244
|
+
it "should be valid for objects included in class array" do
|
245
|
+
param = Apipie::ParamDescription.new(method_desc, :param, [Fixnum, String])
|
246
|
+
expect { param.validate("1") }.should_not raise_error
|
247
|
+
expect { param.validate(Fixnum) }.should raise_error
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
174
251
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'rake tasks' do
|
4
|
+
include_context "rake"
|
5
|
+
|
6
|
+
before do
|
7
|
+
Apipie.stub(:reload_documentation)
|
8
|
+
subject.invoke(*task_args)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'static pages' do
|
12
|
+
|
13
|
+
let(:apidoc_html) do
|
14
|
+
File.read("#{doc_output}.html")
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:doc_output) do
|
18
|
+
File.join(::Rails.root, 'doc', 'apidoc')
|
19
|
+
end
|
20
|
+
|
21
|
+
after do
|
22
|
+
Dir["#{doc_output}*"].each { |static_file| FileUtils.rm_rf(static_file) }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'apipie:static' do
|
26
|
+
it "generates static files for the default version of apipie docs" do
|
27
|
+
apidoc_html.should =~ /Test app #{Apipie.configuration.default_version}/
|
28
|
+
end
|
29
|
+
|
30
|
+
it "includes the stylesheets" do
|
31
|
+
apidoc_html.should include('./apidoc/stylesheets/bundled/bootstrap.min.css')
|
32
|
+
File.should exist(File.join(doc_output, 'stylesheets/bundled/bootstrap.min.css'))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'apipie:static[2.0]' do
|
37
|
+
it "generates static files for the default version of apipie docs" do
|
38
|
+
apidoc_html.should =~ /Test app 2.0/
|
39
|
+
end
|
40
|
+
|
41
|
+
it "includes the stylesheets" do
|
42
|
+
apidoc_html.should include('./apidoc/stylesheets/bundled/bootstrap.min.css')
|
43
|
+
File.should exist(File.join(doc_output, 'stylesheets/bundled/bootstrap.min.css'))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'apipie:cache' do
|
49
|
+
let(:cache_output) do
|
50
|
+
File.join(::Rails.root, 'public', 'apipie-cache')
|
51
|
+
end
|
52
|
+
|
53
|
+
let(:apidoc_html) do
|
54
|
+
File.read("#{cache_output}.html")
|
55
|
+
end
|
56
|
+
|
57
|
+
after do
|
58
|
+
Dir["#{cache_output}*"].each { |static_file| FileUtils.rm_rf(static_file) }
|
59
|
+
end
|
60
|
+
|
61
|
+
it "generates cache files" do
|
62
|
+
File.should exist(File.join(cache_output, 'apidoc.html'))
|
63
|
+
File.should exist(File.join(cache_output, 'apidoc/development.html'))
|
64
|
+
File.should exist(File.join(cache_output, 'apidoc/development/users.html'))
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -4,6 +4,24 @@ describe Apipie::ResourceDescription do
|
|
4
4
|
|
5
5
|
let(:dsl_data) { ActionController::Base.send(:_apipie_dsl_data_init) }
|
6
6
|
|
7
|
+
describe "metadata" do
|
8
|
+
|
9
|
+
it "should return nil when no metadata is provided" do
|
10
|
+
resource = Apipie::ResourceDescription.new(ApplicationController, "dummy", dsl_data)
|
11
|
+
resource.to_json[:metadata].should == nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return the metadata" do
|
15
|
+
meta = {
|
16
|
+
:lenght => 32,
|
17
|
+
:weight => '830g'
|
18
|
+
}
|
19
|
+
resource = Apipie::ResourceDescription.new(ApplicationController, "dummy", dsl_data.update(:meta => meta))
|
20
|
+
resource.to_json[:metadata].should == meta
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
7
25
|
describe "methods descriptions" do
|
8
26
|
|
9
27
|
before(:each) do
|
data/spec/lib/validator_spec.rb
CHANGED
@@ -43,4 +43,13 @@ describe Apipie::Validator do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
end
|
46
|
+
|
47
|
+
describe 'ArrayClassValidator' do
|
48
|
+
it "should validate by object class" do
|
49
|
+
validator = Apipie::Validator::ArrayClassValidator.new(params_desc, [Fixnum, String])
|
50
|
+
validator.validate("1").should be_true
|
51
|
+
validator.validate(1).should be_true
|
52
|
+
validator.validate({ 1 => 1 }).should be_false
|
53
|
+
end
|
54
|
+
end
|
46
55
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'bundler/setup'
|
3
3
|
|
4
4
|
ENV["RAILS_ENV"] ||= 'test'
|
5
|
+
APIPIE_ROOT = File.expand_path('../..', __FILE__)
|
5
6
|
require File.expand_path("../dummy/config/environment", __FILE__)
|
6
7
|
|
7
8
|
require 'rspec/rails'
|
@@ -11,7 +12,7 @@ require 'apipie-rails'
|
|
11
12
|
|
12
13
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
13
14
|
# in spec/support/ and its subdirectories.
|
14
|
-
Dir[
|
15
|
+
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
|
15
16
|
|
16
17
|
RSpec.configure do |config|
|
17
18
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rake"
|
2
|
+
|
3
|
+
# inspired by http://robots.thoughtbot.com/test-rake-tasks-like-a-boss
|
4
|
+
shared_context "rake" do
|
5
|
+
let(:rake) { Rake::Application.new }
|
6
|
+
let(:task_name) { rake.parse_task_string(self.class.description).first }
|
7
|
+
let(:task_args) { rake.parse_task_string(self.class.description).last }
|
8
|
+
let(:task_path) { "lib/tasks/apipie" }
|
9
|
+
subject { rake[task_name] }
|
10
|
+
|
11
|
+
def loaded_files_excluding_current_rake_file
|
12
|
+
$".reject {|file| file == File.expand_path("#{task_path}.rake", APIPIE_ROOT) }
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
Rake.application = rake
|
17
|
+
Rake.application.rake_require(task_path, [APIPIE_ROOT], loaded_files_excluding_current_rake_file)
|
18
|
+
|
19
|
+
Rake::Task.define_task(:environment)
|
20
|
+
end
|
21
|
+
end
|