apipie-rails 0.0.24 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gitignore +1 -1
  2. data/.travis.yml +6 -0
  3. data/CHANGELOG.md +97 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.rails30 +5 -0
  6. data/Gemfile.rails32 +5 -0
  7. data/Gemfile.rails40 +5 -0
  8. data/Gemfile.rails41 +5 -0
  9. data/README.rst +126 -11
  10. data/apipie-rails.gemspec +1 -1
  11. data/app/controllers/apipie/apipies_controller.rb +3 -0
  12. data/app/helpers/apipie_helper.rb +9 -0
  13. data/app/views/apipie/apipies/_metadata.erb +1 -0
  14. data/app/views/apipie/apipies/_method_detail.erb +46 -0
  15. data/app/views/apipie/apipies/_params.html.erb +12 -0
  16. data/app/views/apipie/apipies/_params_plain.html.erb +4 -0
  17. data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
  18. data/app/views/apipie/apipies/method.html.erb +1 -37
  19. data/app/views/apipie/apipies/plain.html.erb +1 -0
  20. data/app/views/apipie/apipies/resource.html.erb +6 -37
  21. data/app/views/apipie/apipies/static.html.erb +1 -0
  22. data/lib/apipie/application.rb +16 -2
  23. data/lib/apipie/configuration.rb +8 -2
  24. data/lib/apipie/dsl_definition.rb +25 -6
  25. data/lib/apipie/error_description.rb +22 -10
  26. data/lib/apipie/extractor.rb +2 -1
  27. data/lib/apipie/extractor/writer.rb +8 -6
  28. data/lib/apipie/method_description.rb +7 -4
  29. data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
  30. data/lib/apipie/param_description.rb +25 -4
  31. data/lib/apipie/resource_description.rb +8 -4
  32. data/lib/apipie/routing.rb +1 -0
  33. data/lib/apipie/validator.rb +71 -3
  34. data/lib/apipie/version.rb +1 -1
  35. data/lib/tasks/apipie.rake +26 -5
  36. data/spec/controllers/apipies_controller_spec.rb +2 -0
  37. data/spec/controllers/concerns_controller_spec.rb +1 -1
  38. data/spec/controllers/users_controller_spec.rb +130 -19
  39. data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +1 -0
  40. data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +22 -20
  41. data/spec/dummy/app/controllers/concerns/sample_controller.rb +32 -30
  42. data/spec/dummy/app/controllers/users_controller.rb +18 -5
  43. data/spec/lib/method_description_spec.rb +22 -0
  44. data/spec/lib/param_description_spec.rb +77 -0
  45. data/spec/lib/rake_spec.rb +68 -0
  46. data/spec/lib/resource_description_spec.rb +18 -0
  47. data/spec/lib/validator_spec.rb +9 -0
  48. data/spec/spec_helper.rb +2 -1
  49. data/spec/support/rake.rb +21 -0
  50. metadata +20 -7
  51. data/CHANGELOG +0 -72
@@ -18,6 +18,7 @@ module Api
18
18
  def_param_group :arch do
19
19
  param :architecture, Hash, :required => true do
20
20
  param :name, String, :required => true
21
+ param :description, String, :required => true
21
22
  param_group :timestamps
22
23
  end
23
24
  end
@@ -1,29 +1,31 @@
1
1
  module Api
2
2
  module V2
3
- class Nested::ArchitecturesController < V2::BaseController
4
- resource_description { name 'Architectures' }
5
- api :GET, "/nested/architectures/", "List all nested architectures."
6
- def index
7
- end
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
- api :GET, "/nested/architectures/:id/", "Show a nested architecture."
10
- def show
11
- end
10
+ api :GET, "/nested/architectures/:id/", "Show a nested architecture."
11
+ def show
12
+ end
12
13
 
13
- api :POST, "/nested/architectures/", "Create a nested architecture."
14
- param_group :arch, Api::V1::ArchitecturesController
15
- def create
16
- end
14
+ api :POST, "/nested/architectures/", "Create a nested architecture."
15
+ param_group :arch, Api::V1::ArchitecturesController
16
+ def create
17
+ end
17
18
 
18
- api :PUT, "/nested/architectures/:id/", "Update a nested architecture."
19
- param :architecture, Hash, :required => true do
20
- param :name, String
21
- end
22
- def update
23
- end
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
- api :DELETE, "/architecturess/:id/", "Delete a nested architecture."
26
- def destroy
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::SampleController
2
- extend Apipie::DSL::Concern
1
+ module Concerns
2
+ module SampleController
3
+ extend Apipie::DSL::Concern
3
4
 
4
- api :GET, '/:controller_path'
5
- def index
6
- render :text => "OK #{params.inspect}"
7
- end
5
+ api :GET, '/:controller_path'
6
+ def index
7
+ render :text => "OK #{params.inspect}"
8
+ end
8
9
 
9
- api :GET, '/:resource_id/:id'
10
- param :id, String
11
- def show
12
- render :text => "OK #{params.inspect}"
13
- end
10
+ api :GET, '/:resource_id/:id'
11
+ param :id, String
12
+ def show
13
+ render :text => "OK #{params.inspect}"
14
+ end
14
15
 
15
- def_param_group :concern do
16
- param :concern, Hash, :required => true, :action_aware => true do
17
- param :name, String, "Name of a :concern"
18
- param :concern_type, String
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
- api :POST, '/:resource_id', "Create a :concern"
23
- param_group :concern
24
- def create
25
- render :text => "OK #{params.inspect}"
26
- end
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
- api :PUT, '/:resource_id/:id'
29
- param :id, String
30
- param_group :concern
31
- def update
32
- render :text => "OK #{params.inspect}"
33
- end
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
- api :GET, '/:resource_id/:custom_subst'
36
- def custom
37
- render :text => "OK #{params.inspect}"
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 :resource_param, Hash, :desc => 'Param description for all methods' do
9
- param :ausername, String, :desc => "Username for login", :required => true
10
- param :apassword, String, :desc => "Password for login", :required => true
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", "Create user"
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
@@ -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[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
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