diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index 755b605..a7d0bcf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /deps erl_crash.dump *.ez +.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index a8df158..a8ac01b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Add `nullable:` option to `JsonSchema.relationship` function * Handle `x-nullable` schemas in `SchemaTest` * Add `deprecated` flag for operations + * Add `add_module/2` function to add path and schema definitions not in controllers. # 0.8.0 diff --git a/lib/helpers/misc_helpers.ex b/lib/helpers/helpers.ex similarity index 59% rename from lib/helpers/misc_helpers.ex rename to lib/helpers/helpers.ex index 100409d..2665472 100644 --- a/lib/helpers/misc_helpers.ex +++ b/lib/helpers/helpers.ex @@ -1,4 +1,4 @@ -defmodule Helpers.MiscHelpers do +defmodule PhoenixSwagger.Helpers do def merge_definitions(definitions, swagger_map = %{definitions: existing}) do %{swagger_map | definitions: Map.merge(existing, definitions)} @@ -9,6 +9,17 @@ defmodule Helpers.MiscHelpers do %{swagger_map | paths: paths} end + def swagger_map(swagger_map) do + Map.update(swagger_map, :definitions, %{}, &(&1)) + |> Map.update(:paths, %{}, &(&1)) + end + + def extract_args(action) do + [ + %{verb: action |> String.to_atom, path: ""} + ] + end + defp merge_conflicts(_key, value1, value2) do Map.merge(value1, value2) end diff --git a/lib/mix/tasks/swagger.generate.ex b/lib/mix/tasks/swagger.generate.ex index 42187e1..e309675 100644 --- a/lib/mix/tasks/swagger.generate.ex +++ b/lib/mix/tasks/swagger.generate.ex @@ -1,7 +1,7 @@ defmodule Mix.Tasks.Phx.Swagger.Generate do use Mix.Task require Logger - alias Helpers.MiscHelpers, as: Helpers + alias PhoenixSwagger.Helpers, as: Helpers @recursive true @@ -130,7 +130,7 @@ defmodule Mix.Tasks.Phx.Swagger.Generate do Code.ensure_compiled?(controller) -> %{ controller: controller, - path: path |> format_path, + path: format_path(path), swagger_fun: swagger_fun, verb: verb } diff --git a/lib/phoenix_swagger.ex b/lib/phoenix_swagger.ex index 96a91a1..523c2e4 100644 --- a/lib/phoenix_swagger.ex +++ b/lib/phoenix_swagger.ex @@ -3,7 +3,7 @@ defmodule PhoenixSwagger do use Application alias PhoenixSwagger.Path alias PhoenixSwagger.Path.PathObject - alias Helpers.MiscHelpers, as: Helpers + alias PhoenixSwagger.Helpers, as: Helpers @moduledoc """ The PhoenixSwagger module provides macros for defining swagger operations and schemas. @@ -218,62 +218,50 @@ defmodule PhoenixSwagger do |> add_module(SimpleWeb.UserSocket) """ - def add_module(struct, module) do + def add_module(swagger_map, module) do functions = module.__info__(:functions) - paths = get_paths(functions, struct, module) + swagger_map + |> get_paths(module, functions) + |> get_schemas(module, functions) + end + defp get_schemas(swagger_map, module, functions) do Enum.map(functions, fn {action, _arg} -> build_schemas(action, module) end) |> Enum.filter(&!is_nil(&1)) - |> Enum.reduce(swagger_map(paths), &Helpers.merge_definitions/2) + |> Enum.reduce(Helpers.swagger_map(swagger_map), &Helpers.merge_definitions/2) end - - def build_schemas(function, module) do + defp build_schemas(function, module) do if is_schema?(function), do: apply(module, function, []) end - defp is_schema?(function) do function |> Atom.to_string |> String.contains?("swagger_definitions") end - defp get_paths(functions, struct, module) do + defp get_paths(swagger_map, module, functions) do Enum.map(functions, fn {action, _arg} -> build_path(action, module) end) |> Enum.filter(&!is_nil(&1)) - |> Enum.reduce(swagger_map(struct), &Helpers.merge_paths/2) + |> Enum.reduce(Helpers.swagger_map(swagger_map), &Helpers.merge_paths/2) end - - def swagger_map(swagger_map) do - Map.update(swagger_map, :definitions, %{}, &(&1)) - |> Map.update(:paths, %{}, &(&1)) - end - - defp build_path(function, module) do #room for improvement here for sure, comments? - case is_path?(function) do - {true, action} -> - apply(module, function, extract_args(action)) - {false, _action} -> - nil + defp build_path(function, module) do + if is_path?(function) do + action = + function + |> get_action + apply(module, function, Helpers.extract_args(action)) end end - - defp is_path?(function) do #room for improvement here for sure, comments? - funct_string = - function - |> Atom.to_string - - contains = - funct_string - |> String.contains?("swagger_path") - - {contains, String.replace(funct_string, "swagger_path_", "")} + defp is_path?(function) do + function + |> Atom.to_string + |> String.contains?("swagger_path") end - - defp extract_args(action) do - [ - %{verb: action |> String.to_atom, path: ""} - ] + defp get_action(function) do + function + |> Atom.to_string + |> String.replace("swagger_path_", "") end @doc false diff --git a/mix.exs b/mix.exs index 26eb63b..9bc9699 100644 --- a/mix.exs +++ b/mix.exs @@ -55,7 +55,7 @@ defmodule PhoenixSwagger.Mixfile do defp deps do [ {:poison, "~> 2.2 or ~> 3.0"}, - {:ex_json_schema, "~> 0.5", optional: true}, + {:ex_json_schema, "~> 0.5.0", optional: true}, {:plug, "~> 1.4"}, {:ex_doc, "~> 0.18", only: :dev, runtime: false}, {:dialyxir, "~> 0.5", only: :dev, runtime: false} diff --git a/mix.lock b/mix.lock index d37ddaf..ac303db 100644 --- a/mix.lock +++ b/mix.lock @@ -2,7 +2,7 @@ "dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.1.1", "433136b7f2e99cde88b745b3a0cfc3fbc81fe58b918a09b40fce7f00db4d8187", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.18.3", "f4b0e4a2ec6f333dccf761838a4b253d75e11f714b85ae271c9ae361367897b7", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "ex_json_schema": {:hex, :ex_json_schema, "0.5.6", "9a96edd51a00fc005e12a773a7a79e507a77855e69fcb3d9a02f7f39c3265c03", [:mix], [], "hexpm"}, + "ex_json_schema": {:hex, :ex_json_schema, "0.5.8", "9758444f560ebf5e1c5cb37d41a122707939f75136c7a79c4ff4ca6ad5283fb9", [:mix], [], "hexpm"}, "mime": {:hex, :mime, "1.2.0", "78adaa84832b3680de06f88f0997e3ead3b451a440d183d688085be2d709b534", [:mix], [], "hexpm"}, "plug": {:hex, :plug, "1.5.0", "224b25b4039bedc1eac149fb52ed456770b9678bbf0349cdd810460e1e09195b", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, diff --git a/test/validator_test.exs b/test/validator_test.exs index 4df424c..d30610d 100644 --- a/test/validator_test.exs +++ b/test/validator_test.exs @@ -62,16 +62,21 @@ defmodule ValidatorTest do assert :ok = Validator.validate("/get/pets/{id}", %{"id" => 1}) assert {:error, :resource_not_exists} = Validator.validate("/pets", %{"id" => 1}) assert {:error, - [{"Required property id was not present.", "#"}, - {"Required property pet was not present.", "#"}], "/post/pets"} = Validator.validate("/post/pets", %{}) + [ + {"Required property id was not present.", "#"}, + {"Required property pet was not present.", "#"} + ], "/post/pets"} + = Validator.validate("/post/pets", %{}) assert {:error, [{"Type mismatch. Expected Integer but got String.", "#/id"}, {"Required property pet was not present.", "#"}], "/post/pets"} = Validator.validate("/post/pets", %{"id" => "wrong_id"}) assert {:error, "Required property pet was not present.", "#"} = Validator.validate("/post/pets", %{"id" => 1}) assert {:error, - [{"Required property name was not present.", "#/pet"}, - {"Required property tag was not present.", "#/pet"}], "/post/pets"} - = Validator.validate("/post/pets", %{"id" => 1, "pet" => %{}}) + [ + {"Required property name was not present.", "#/pet"}, + {"Required property tag was not present.", "#/pet"} + ], "/post/pets"} + = Validator.validate("/post/pets", %{"id" => 1, "pet" => %{}}) assert {:error, "Required property tag was not present.", "#/pet"} = Validator.validate("/post/pets", %{"id" => 1, "pet" => %{"name" => "pet_name"}}) assert :ok = Validator.validate("/post/pets", %{"id" => 1, "pet" => %{"name" => "pet_name", "tag" => "pet_tag"}})