Skip to content

Commit

Permalink
Merge pull request #55 from aaronrenner/make_camelize_model_propertie…
Browse files Browse the repository at this point in the history
…s_configurable

Made camelize model properties configurable and fixed swagger_model name capitalization issue
  • Loading branch information
richhollis committed May 30, 2014
2 parents cab82a4 8bbef3a commit aa6d9d4
Show file tree
Hide file tree
Showing 8 changed files with 412 additions and 17 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 102,12 @@ The following table shows all the current configuration options and their defaul
<td>:pretty</td>
</tr>

<tr>
<td><b>camelize_model_properties</b></td>
<td>Camelizes property names of models. For example, a property name called first_name would be converted to firstName.</td>
<td>true</td>
</tr>

</tbody>
</table>

Expand Down Expand Up @@ -174,19 180,19 @@ end
### DRYing up common documentation

Suppose you have a header or a parameter that must be present on several controllers and methods. Instead of duplicating it on all the controllers you can do this on your API base controller:

```ruby
class Api::BaseController < ActionController::Base
class << self
Swagger::Docs::Generator::set_real_methods

def inherited(subclass)
super
subclass.class_eval do
setup_basic_api_documentation
end
end

private
def setup_basic_api_documentation
[:index, :show, :create, :update, :delete].each do |api_action|
Expand All @@ -198,7 204,7 @@ class Api::BaseController < ActionController::Base
end
end
```

And then use it as a superclass to all you API controllers. All the subclassed controllers will have the same documentation applied to them.

### DSL Methods
Expand Down
2 changes: 2 additions & 0 deletions lib/swagger/docs.rb
Original file line number Diff line number Diff line change
@@ -1,5 1,7 @@
require "swagger/docs/config"
require "swagger/docs/dsl"
require "swagger/docs/api_declaration_file_metadata"
require "swagger/docs/api_declaration_file"
require "swagger/docs/generator"
require "swagger/docs/impotent_methods"
require "swagger/docs/methods"
Expand Down
120 changes: 120 additions & 0 deletions lib/swagger/docs/api_declaration_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 1,120 @@
module Swagger
module Docs
class ApiDeclarationFile
attr_reader :metadata, :apis

def initialize(metadata, apis, models)
@metadata = metadata
@apis = camelize_keys_deep apis
@models = models
end

def generate_resource
resource = build_resource_root_hash
# Add the already-normalized models to the resource.
resource = resource.merge({:models => models}) if models.present?
resource
end

def base_path
metadata.base_path
end

def path
metadata.path
end

def swagger_version
metadata.swagger_version
end

def api_version
metadata.api_version
end

def controller_base_path
metadata.controller_base_path
end

def camelize_model_properties
metadata.camelize_model_properties
end

def resource_path
demod
end

def resource_file_path
trim_leading_slash(debased_path.to_s.underscore)
end

def models
normalize_model_properties @models
end

private

def build_resource_root_hash
{
"apiVersion" => api_version,
"swaggerVersion" => swagger_version,
"basePath" => base_path,
"resourcePath" => resource_path,
"apis" => apis,
"resourceFilePath" => resource_file_path
}
end

def normalize_model_properties(models)
Hash[
models.map do |k, v|
if camelize_model_properties
[k.to_s, camelize_keys_deep(v)]
else
[k.to_s, stringify_keys_deep(v)]
end
end]
end

def demod
"#{debased_path.to_s.camelize}".demodulize.camelize.underscore
end

def debased_path
path.gsub("#{controller_base_path}", "")
end

def trim_leading_slash(str)
return str if !str
str.gsub(/\A\/ /, '')
end

def camelize_keys_deep(obj)
process_keys_deep(obj){|key| key.to_s.camelize(:lower)}
end

def stringify_keys_deep(obj)
process_keys_deep(obj){|key| key.to_s}
end

def process_keys_deep(obj, &block)
if obj.is_a? Hash
Hash[
obj.map do |k, v|
new_key = block.call(k)
new_value = process_keys_deep v, &block
[new_key, new_value]
end
]
elsif obj.is_a? Array
new_value = obj.collect do |a|
process_keys_deep a, &block
end
else
obj
end
end

end
end
end
18 changes: 18 additions & 0 deletions lib/swagger/docs/api_declaration_file_metadata.rb
Original file line number Diff line number Diff line change
@@ -0,0 1,18 @@
module Swagger
module Docs
class ApiDeclarationFileMetadata
DEFAULT_SWAGGER_VERSION = "1.2"

attr_reader :api_version, :path, :base_path, :controller_base_path, :swagger_version, :camelize_model_properties

def initialize(api_version, path, base_path, controller_base_path, options={})
@api_version = api_version
@path = path
@base_path = base_path
@controller_base_path = controller_base_path
@swagger_version = options.fetch(:swagger_version, DEFAULT_SWAGGER_VERSION)
@camelize_model_properties = options.fetch(:camelize_model_properties, true)
end
end
end
end
20 changes: 8 additions & 12 deletions lib/swagger/docs/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 54,7 @@ def generate_docs(apis=nil)
end

def generate_doc(api_version, settings, config)
root = { :api_version => api_version, :swagger_version => "1.2", :base_path => settings[:base_path] "/", :apis => []}
root = { "apiVersion" => api_version, "swaggerVersion" => "1.2", "basePath" => settings[:base_path] "/", :apis => []}
results = {:processed => [], :skipped => []}
resources = []

Expand All @@ -71,8 71,7 @@ def generate_doc(api_version, settings, config)
root[:apis] << resource_api
end
end
root[:resources] = resources
camelize_keys_deep!(root)
root['resources'] = resources
results[:root] = root
results
end
Expand Down Expand Up @@ -134,15 133,12 @@ def process_path(path, root, config, settings)
end

def generate_resource(path, apis, models, settings, root, config)
debased_path = get_debased_path(path, settings[:controller_base_path])
demod = "#{debased_path.to_s.camelize}".demodulize.camelize.underscore
resource_path = trim_leading_slash(debased_path.to_s.underscore)
resource = root.merge({:resource_path => "#{demod}", :apis => apis})
camelize_keys_deep!(resource)
# Add the already-normalized models to the resource.
resource = resource.merge({:models => models}) if models.present?
resource[:resource_file_path] = resource_path
resource
metadata = ApiDeclarationFileMetadata.new(root["apiVersion"], path, root["basePath"],
settings[:controller_base_path],
camelize_model_properties: config.fetch(:camelize_model_properties, true),
swagger_version: root["swaggerVersion"])
declaration = ApiDeclarationFile.new(metadata, apis, models)
declaration.generate_resource
end

def get_route_path_apis(path, route, klass, settings, config)
Expand Down
55 changes: 55 additions & 0 deletions spec/lib/swagger/docs/api_declaration_file_metadata_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 1,55 @@
require 'spec_helper'

describe Swagger::Docs::ApiDeclarationFileMetadata do

describe "#initialize" do
it "sets the api_version property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.api_version).to eq("1.0")
end

it "sets the path property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.path).to eq("path")
end

it "sets the base_path property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.base_path).to eq("basePath")
end

it "sets the controller_base_path property" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.controller_base_path).to eq("controllerBasePath")
end

it "defaults the swagger_version property to DEFAULT_SWAGGER_VERSION" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.swagger_version).to eq(described_class::DEFAULT_SWAGGER_VERSION)
end

it "allows the swagger_version property to be_overriden" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath", swagger_version: "2.0")

expect(metadata.swagger_version).to eq("2.0")
end


it "defaults the camelize_model_properties property to true" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath")

expect(metadata.camelize_model_properties).to eq(true)
end

it "allows the camelize_model_properties property to be overidden" do
metadata = described_class.new("1.0", "path", "basePath", "controllerBasePath", camelize_model_properties: false)

expect(metadata.camelize_model_properties).to eq(false)
end
end
end
Loading

0 comments on commit aa6d9d4

Please sign in to comment.