apipie-rails 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -6,6 +6,9 @@ spec/dummy/log/*.log
6
6
  spec/dummy/tmp/
7
7
  .idea
8
8
  Gemfile*.lock
9
+ Gemfile.local
9
10
  .rvmrc
11
+ .ruby-version
12
+ .ruby-gemset
10
13
 
11
14
  .DS_Store
@@ -2,6 +2,17 @@
2
2
  Changelog
3
3
  ===========
4
4
 
5
+ v0.2.3
6
+ ------
7
+
8
+ * add an option to flag an api route as deprecated
9
+ [#268](https://github.com/Apipie/apipie-rails/pull/268) [@komidore64][]
10
+ * add ability to pass additional options to apipie route
11
+ [#269](https://github.com/Apipie/apipie-rails/pull/269) [@exAspArk][]
12
+ * enhanced array validator
13
+ [#259](https://github.com/Apipie/apipie-rails/pull/259) [@mourad-ifeelgoods][]
14
+
15
+
5
16
  v0.2.2
6
17
  ------
7
18
 
@@ -11,8 +22,6 @@ v0.2.2
11
22
  [#257](https://github.com/Apipie/apipie-rails/pull/257) [@ctria][]
12
23
  * reduced rails dependency to development only
13
24
  [#266](https://github.com/Apipie/apipie-rails/pull/266) [@klobuczek][]
14
- * reduced rails dependency to development only
15
- [#266](https://github.com/Apipie/apipie-rails/pull/266) [@klobuczek][]
16
25
  * add more options to apipie:cache to generate only parts of the
17
26
  static pages
18
27
  [#262](https://github.com/Apipie/apipie-rails/pull/262) [@mbacovsky][]
@@ -174,3 +183,6 @@ v0.0.15
174
183
  [@lsylvester]: https://github.com/lsylverster
175
184
  [@ctria]: https://github.com/ctria
176
185
  [@klobuczek]: https://github.com/klobuczek
186
+ [@komidore64]: https://github.com/komidore64
187
+ [@exAspArk]: https://github.com/exAspArk
188
+ [@mourad-ifeelgoods]: https://github.com/mourad-ifeelgoods
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
+
5
+ # load local gemfile
6
+ local_gemfile = File.join(File.dirname(__FILE__), 'Gemfile.local')
7
+ self.instance_eval(Bundler.read_file(local_gemfile)) if File.exist?(local_gemfile)
data/README.rst CHANGED
@@ -669,14 +669,14 @@ Check parameter value against given regular expression.
669
669
  param :regexp_param, /^[0-9]* years/, :desc => "regexp param"
670
670
 
671
671
 
672
- ArrayValidator
672
+ EnumValidator
673
673
  --------------
674
674
 
675
675
  Check if parameter value is included given array.
676
676
 
677
677
  .. code:: ruby
678
678
 
679
- param :array_param, [100, "one", "two", 1, 2], :desc => "array validator"
679
+ param :enum_param, [100, "one", "two", 1, 2], :desc => "enum validator"
680
680
 
681
681
 
682
682
  ProcValidator
@@ -724,6 +724,49 @@ override parameters described on resource level.
724
724
  #...
725
725
  end
726
726
 
727
+ ArrayValidator
728
+ --------------
729
+
730
+ Check if the parameter is an array
731
+
732
+ Additional options
733
+ ~~~~~~~~~~~~~~~~~
734
+
735
+ of
736
+ Specify the type of items. if not given it accepts an array of any item type
737
+
738
+ in
739
+ Specifiy an array of valid items value.
740
+
741
+ Examples
742
+ ~~~~~~~~
743
+
744
+ Assert `things` is an array of any items
745
+
746
+ .. code:: ruby
747
+
748
+ param :things, Array
749
+
750
+ Assert `hits` must be an array of integer values
751
+
752
+ .. code:: ruby
753
+
754
+ param :hits, Array, of: Integer
755
+
756
+ Assert `colors` must be an array of valid string values
757
+
758
+ .. code:: ruby
759
+
760
+ param :colors, Array, in: ["red", "green", "blue"]
761
+
762
+
763
+ The retrieving of valid items can be deferred until needed using a lambda. It is evaluated only once
764
+
765
+ .. code:: ruby
766
+
767
+ param :colors, Array, in: -> { Color.all.pluck(:name) }
768
+
769
+
727
770
  NestedValidator
728
771
  -------------
729
772
 
@@ -817,17 +860,21 @@ the resource belong to `config.default_version` ("1.0" by default)
817
860
  api_versions "1", "2"
818
861
  end
819
862
 
820
- api :GET, "/api/users/"
863
+ api :GET, "/api/users/", "List: users"
821
864
  api_version "1"
822
865
  def index
823
866
  # ...
824
867
  end
825
868
 
869
+ api :GET, "/api/users/", "List: users", :deprecated => true
870
+
826
871
  In the example above we say the whole controller/resource is defined
827
872
  for versions "1" and "2", but we override this with explicitly saying
828
873
  `index` belongs only to version "1". Also inheritance works (therefore
829
874
  we can specify the api_version for the parent controller and all
830
- children will know about that).
875
+ children will know about that). Routes can be flagged as deprecated
876
+ and an annotation will be added to them when viewing in the API
877
+ documentation.
831
878
 
832
879
  From the Apipie API perspective, the resources belong to version.
833
880
  With versioning, there are paths like this provided by apipie:
@@ -30,7 +30,12 @@
30
30
  <% api[:methods].each do |m| %>
31
31
  <% m[:apis].each do |a| %>
32
32
  <tr>
33
- <td><a href='<%= m[:doc_url] %><%= @doc[:link_extension] %>'><%= a[:http_method] %> <%= a[:api_url] %></a></td>
33
+ <td>
34
+ <a href='<%= m[:doc_url] %><%= @doc[:link_extension] %>'><%= a[:http_method] %> <%= a[:api_url] %></a>
35
+ <% if a[:deprecated] %>
36
+ <code>DEPRECATED</code>
37
+ <% end %>
38
+ </td>
34
39
  <td width='60%'><%= a[:short_description] %></td>
35
40
  </tr>
36
41
  <% end %>
@@ -18,7 +18,11 @@
18
18
  <% @method[:apis].each do |api| %>
19
19
  <div class='page-header'>
20
20
  <h1>
21
- <%= api[:http_method] %> <%= api[:api_url] %><br>
21
+ <%= api[:http_method] %> <%= api[:api_url] %>
22
+ <% if api[:deprecated] %>
23
+ <code>DEPRECATED</code>
24
+ <% end %>
25
+ <br>
22
26
  <small><%= raw api[:short_description] %></small>
23
27
  </h1>
24
28
  </div>
@@ -47,7 +47,11 @@
47
47
  data-toggle='collapse'
48
48
  data-parent='#accordion'>
49
49
  <%= api[:http_method] %> <%= api[:api_url] %>
50
- </a><br>
50
+ </a>
51
+ <% if api[:deprecated] %>
52
+ <code>DEPRECATED</code>
53
+ <% end %>
54
+ <br>
51
55
  <small><%= raw api[:short_description] %></small>
52
56
  </h2>
53
57
  <% end %>
@@ -79,7 +79,7 @@ module Apipie
79
79
  #
80
80
  def api(method, path, desc = nil, options={}) #:doc:
81
81
  return unless Apipie.active_dsl?
82
- _apipie_dsl_data[:api_args] << [method, path, desc]
82
+ _apipie_dsl_data[:api_args] << [method, path, desc, options]
83
83
  end
84
84
 
85
85
  # Reference other similar method
@@ -5,12 +5,13 @@ module Apipie
5
5
 
6
6
  class Api
7
7
 
8
- attr_accessor :short_description, :path, :http_method
8
+ attr_accessor :short_description, :path, :http_method, :options
9
9
 
10
- def initialize(method, path, desc)
10
+ def initialize(method, path, desc, options)
11
11
  @http_method = method.to_s
12
12
  @path = path
13
13
  @short_description = desc
14
+ @options = options
14
15
  end
15
16
 
16
17
  end
@@ -22,8 +23,8 @@ module Apipie
22
23
  @resource = resource
23
24
  @from_concern = dsl_data[:from_concern]
24
25
 
25
- @apis = dsl_data[:api_args].map do |method, path, desc|
26
- MethodDescription::Api.new(method, concern_subst(path), concern_subst(desc))
26
+ @apis = dsl_data[:api_args].map do |mthd, path, desc, opts|
27
+ MethodDescription::Api.new(mthd, concern_subst(path), concern_subst(desc), opts)
27
28
  end
28
29
 
29
30
  desc = dsl_data[:description] || ''
@@ -113,7 +114,8 @@ module Apipie
113
114
  {
114
115
  :api_url => create_api_url(api),
115
116
  :http_method => api.http_method.to_s,
116
- :short_description => Apipie.app.translate(api.short_description, lang)
117
+ :short_description => Apipie.app.translate(api.short_description, lang),
118
+ :deprecated => api.options[:deprecated]
117
119
  }
118
120
  end
119
121
  end
@@ -1,11 +1,11 @@
1
1
  module Apipie
2
2
  module Routing
3
3
  module MapperExtensions
4
- def apipie
4
+ def apipie(options = {})
5
5
  namespace "apipie", :path => Apipie.configuration.doc_base_url do
6
6
  get 'apipie_checksum', :to => "apipies#apipie_checksum", :format => "json"
7
7
  constraints(:version => /[^\/]+/, :resource => /[^\/]+/, :method => /[^\/]+/) do
8
- get("(:version)/(:resource)/(:method)" => "apipies#index", :as => :apipie)
8
+ get(options.reverse_merge("(:version)/(:resource)/(:method)" => "apipies#index", :as => :apipie))
9
9
  end
10
10
  end
11
11
  end
@@ -134,8 +134,7 @@ module Apipie
134
134
  end
135
135
 
136
136
  # arguments value must be one of given in array
137
- class ArrayValidator < BaseValidator
138
-
137
+ class EnumValidator < BaseValidator
139
138
  def initialize(param_description, argument)
140
139
  super(param_description)
141
140
  @array = argument
@@ -154,6 +153,73 @@ module Apipie
154
153
  end
155
154
  end
156
155
 
156
+ # arguments value must be an array
157
+ class ArrayValidator < Apipie::Validator::BaseValidator
158
+ def initialize(param_description, argument, options={})
159
+ super(param_description)
160
+ @type = argument
161
+ @items_type = options[:of]
162
+ @items_enum = options[:in]
163
+ end
164
+
165
+ def validate(values)
166
+ return false unless process_value(values).respond_to?(:each)
167
+ process_value(values).all? { |v| validate_item(v)}
168
+ end
169
+
170
+ def process_value(values)
171
+ values || []
172
+ end
173
+
174
+ def description
175
+ "Must be an array of #{items}"
176
+ end
177
+
178
+ def self.build(param_description, argument, options={}, block)
179
+ if argument == Array && !block.is_a?(Proc)
180
+ self.new(param_description, argument, options)
181
+ end
182
+ end
183
+
184
+ private
185
+
186
+ def enum
187
+ if @items_enum.kind_of?(Proc)
188
+ @items_enum = Array(@items_enum.call)
189
+ end
190
+ @items_enum
191
+ end
192
+
193
+ def validate_item(value)
194
+ has_valid_type?(value) &&
195
+ is_valid_value?(value)
196
+ end
197
+
198
+ def has_valid_type?(value)
199
+ if @items_type
200
+ value.kind_of?(@items_type)
201
+ else
202
+ true
203
+ end
204
+ end
205
+
206
+ def is_valid_value?(value)
207
+ if enum
208
+ enum.include?(value)
209
+ else
210
+ true
211
+ end
212
+ end
213
+
214
+ def items
215
+ unless enum
216
+ @items_type || "any type"
217
+ else
218
+ enum.inspect
219
+ end
220
+ end
221
+ end
222
+
157
223
  class ArrayClassValidator < BaseValidator
158
224
 
159
225
  def initialize(param_description, argument)
@@ -1,3 +1,3 @@
1
1
  module Apipie
2
- VERSION = '0.2.2'
2
+ VERSION = '0.2.3'
3
3
  end
@@ -517,7 +517,7 @@ EOS2
517
517
 
518
518
  param = a.params[:array_param]
519
519
  param.desc.should eq("\n<p>array validator</p>\n")
520
- param.validator.class.should be(Apipie::Validator::ArrayValidator)
520
+ param.validator.class.should be(Apipie::Validator::EnumValidator)
521
521
  param.validator.instance_variable_get("@array").should
522
522
  eq([100, "one", "two", 1, 2])
523
523
 
@@ -26,6 +26,18 @@ describe Apipie::MethodDescription do
26
26
 
27
27
  end
28
28
 
29
+ describe "deprecated flag" do
30
+ before(:each) do
31
+ @resource = Apipie::ResourceDescription.new(ApplicationController, "dummy")
32
+ end
33
+
34
+ it "should return the deprecated flag when provided" do
35
+ dsl_data[:api_args] = [[:GET, "/foo/bar", "description", :deprecated => true]]
36
+ method = Apipie::MethodDescription.new(:a, @resource, dsl_data)
37
+ method.method_apis_to_json.first[:deprecated].should == true
38
+ end
39
+ end
40
+
29
41
  describe "params descriptions" do
30
42
 
31
43
  before(:each) do
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ module Apipie::Validator
4
+ describe ArrayValidator do
5
+
6
+ let(:param_desc) { double(:param_desc) }
7
+
8
+ context "with no constraint" do
9
+ let(:validator) { ArrayValidator.new(param_desc, Array) }
10
+ it "accepts any array" do
11
+ expect(validator.validate([42, 'string', true])).to eq(true)
12
+ end
13
+
14
+ it "accepts empty array" do
15
+ expect(validator.validate([])).to eq(true)
16
+ expect(validator.validate(nil)).to eq(true)
17
+ end
18
+
19
+ it "does not accepts non array" do
20
+ expect(validator.validate(42)).to eq(false)
21
+ expect(validator.validate(true)).to eq(false)
22
+ expect(validator.validate('string')).to eq(false)
23
+ end
24
+ end
25
+
26
+ context "with a constraint on items type" do
27
+ let(:validator) { ArrayValidator.new(param_desc, Array, of: String) }
28
+
29
+ it "accepts array of specified type" do
30
+ expect(validator.validate(['string1', 'string2'])).to eq(true)
31
+ end
32
+
33
+ it "accepts empty array" do
34
+ expect(validator.validate([])).to eq(true)
35
+ end
36
+
37
+ it "does not accepts array with other types" do
38
+ expect(validator.validate(['string1', true])).to eq(false)
39
+ end
40
+ end
41
+
42
+ context "with a constraint on items value" do
43
+ let(:validator) { ArrayValidator.new(param_desc, Array, in: [42, 'string', true]) }
44
+
45
+ it "accepts array of valid values" do
46
+ expect(validator.validate([42, 'string'])).to eq(true)
47
+ end
48
+
49
+ it "accepts empty array" do
50
+ expect(validator.validate([])).to eq(true)
51
+ end
52
+
53
+ it "does not accepts array with invalid values" do
54
+ expect(validator.validate([42, 'string', 'foo'])).to eq(false)
55
+ end
56
+
57
+ it "accepts a proc as list of valid values" do
58
+ validator = ArrayValidator.new(param_desc, Array, in: -> { [42, 'string', true] })
59
+ expect(validator.validate([42, 'string'])).to eq(true)
60
+ expect(validator.validate([42, 'string', 'foo'])).to eq(false)
61
+ end
62
+ end
63
+
64
+ end
65
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apipie-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-07-24 00:00:00.000000000 Z
13
+ date: 2014-08-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -297,6 +297,7 @@ files:
297
297
  - spec/lib/rake_spec.rb
298
298
  - spec/lib/resource_description_spec.rb
299
299
  - spec/lib/validator_spec.rb
300
+ - spec/lib/validators/array_validator_spec.rb
300
301
  - spec/spec_helper.rb
301
302
  - spec/support/rake.rb
302
303
  homepage: http://github.com/Pajk/apipie-rails
@@ -384,6 +385,7 @@ test_files:
384
385
  - spec/lib/rake_spec.rb
385
386
  - spec/lib/resource_description_spec.rb
386
387
  - spec/lib/validator_spec.rb
388
+ - spec/lib/validators/array_validator_spec.rb
387
389
  - spec/spec_helper.rb
388
390
  - spec/support/rake.rb
389
391
  has_rdoc: