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.
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