From 44b580127737c5d49acfaa30a40ec1f6b786705a Mon Sep 17 00:00:00 2001 From: Shane Logsdon Date: Sun, 21 Dec 2014 20:30:48 -0500 Subject: [PATCH] cleanup. fixes #25. prep for #16 --- config/config.exs | 3 + lib/mix/tasks/compile/sugar.ex | 3 +- lib/mix/tasks/server.ex | 9 +- lib/mix/tasks/sugar/init.ex | 4 - lib/sugar/app.ex | 30 +-- lib/sugar/config.ex | 35 +++ lib/sugar/controller.ex | 40 +-- lib/sugar/exceptions.ex | 278 --------------------- lib/sugar/router.ex | 6 +- mix.exs | 2 +- test/fixtures/templates/foo/index.html.eex | 0 test/fixtures/templates/index.html.eex | 0 test/sugar/app_test.exs | 4 - test/sugar/config_test.exs | 17 ++ test/sugar/controller_test.exs | 34 +-- test/sugar/exceptions_test.exs | 27 -- 16 files changed, 104 insertions(+), 388 deletions(-) create mode 100644 config/config.exs create mode 100644 lib/sugar/config.ex delete mode 100644 lib/sugar/exceptions.ex create mode 100644 test/fixtures/templates/foo/index.html.eex create mode 100644 test/fixtures/templates/index.html.eex create mode 100644 test/sugar/config_test.exs delete mode 100644 test/sugar/exceptions_test.exs diff --git a/config/config.exs b/config/config.exs new file mode 100644 index 0000000..b1c5377 --- /dev/null +++ b/config/config.exs @@ -0,0 +1,3 @@ +use Mix.Config + +config :sugar, views_dir: "test/fixtures/templates" \ No newline at end of file diff --git a/lib/mix/tasks/compile/sugar.ex b/lib/mix/tasks/compile/sugar.ex index f0c0858..8439d4c 100644 --- a/lib/mix/tasks/compile/sugar.ex +++ b/lib/mix/tasks/compile/sugar.ex @@ -68,7 +68,8 @@ defmodule Mix.Tasks.Compile.Sugar do Mix.shell.info "Generated #{name}" end) - compiled = Sugar.Templates.get_all_templates + # compiled = + Sugar.Templates.get_all_templates |> Map.keys # Mix.Utils.write_manifest(manifest, compiled) diff --git a/lib/mix/tasks/server.ex b/lib/mix/tasks/server.ex index 37618aa..d82b882 100644 --- a/lib/mix/tasks/server.ex +++ b/lib/mix/tasks/server.ex @@ -31,13 +31,10 @@ defmodule Mix.Tasks.Server do end defp add_config(options) do - config = Sugar.App.config + router = Sugar.Config.get(:placid, :router, Router) + config = Sugar.Config.get(router) || [] - if Keyword.has_key? config, :server do - Keyword.merge config[:server], options - else - options - end + Keyword.merge config, options end def binary_to_integer(port) do diff --git a/lib/mix/tasks/sugar/init.ex b/lib/mix/tasks/sugar/init.ex index c913160..f61df13 100644 --- a/lib/mix/tasks/sugar/init.ex +++ b/lib/mix/tasks/sugar/init.ex @@ -18,9 +18,7 @@ defmodule Mix.Tasks.Sugar.Init do """ def run(args) do - IO.inspect args opts = OptionParser.parse(args, switches: [no_repo: :boolean, path: :string, priv_path: :string]) - IO.inspect opts do_init elem(opts, 0) end @@ -34,8 +32,6 @@ defmodule Mix.Tasks.Sugar.Init do priv_path: "priv" ] |> Keyword.merge opts - IO.inspect assigns - # Priviliged create_directory "#{assigns[:priv_path]}" create_directory "#{assigns[:priv_path]}/static" diff --git a/lib/sugar/app.ex b/lib/sugar/app.ex index a8dfe05..6609839 100644 --- a/lib/sugar/app.ex +++ b/lib/sugar/app.ex @@ -12,13 +12,7 @@ defmodule Sugar.App do """ def run(opts) do IO.puts "Starting Sugar on port #{get_port(opts)}..." - - if Keyword.has_key? Sugar.App.config, :router do - router = Sugar.App.config[:router] - else - router = Router - end - + router = Sugar.Config.get(:sugar, :router, Router) Plug.Adapters.Cowboy.http router, [], opts end @@ -39,7 +33,8 @@ defmodule Sugar.App do """ def start(_type, _args) do :ok = Application.ensure_started(:templates) - Sugar.Views.Finder.all("lib/views") + Sugar.Config.get(:sugar, :views_dir, "lib/#{Mix.Project.config[:app]}/views") + |> Sugar.Views.Finder.all |> Sugar.Templates.compile Sugar.Supervisor.start_link end @@ -72,23 +67,4 @@ defmodule Sugar.App do abs(opts[:port]) end end - - @doc """ - Loads userland configuration if available. - - ## Returns - - `Keyword` - """ - def config do - config = Keyword.new - if loaded? Config do - config = apply(Config, :config, []) - end - config - end - - defp loaded?(module) do - is_tuple :code.is_loaded(module) - end end diff --git a/lib/sugar/config.ex b/lib/sugar/config.ex new file mode 100644 index 0000000..09ae359 --- /dev/null +++ b/lib/sugar/config.ex @@ -0,0 +1,35 @@ +defmodule Sugar.Config do + @moduledoc false + + @default_options [ + http: [ port: 4000 ], + https: [ certfile: "", + keyfile: "", + port: 4443 ] + ] + + def get(module) when module != :sugar do + get(:sugar, module) + end + def get(:sugar, key) do + _get(key) + end + def get(module, key) do + _get(module)[key] + end + def get(:sugar, key, default) do + get(:sugar, key) || default + end + def get(module, key, default) do + get(module, key) || default + end + + defp _get(key) do + env = Application.get_env(:sugar, key) + if is_list(env) do + @default_options |> Keyword.merge(env) + else + env + end + end +end diff --git a/lib/sugar/controller.ex b/lib/sugar/controller.ex index 42853c1..20a1f24 100644 --- a/lib/sugar/controller.ex +++ b/lib/sugar/controller.ex @@ -155,14 +155,11 @@ defmodule Sugar.Controller do end @doc """ - Sends a normal response. + Sends a normal response. Automatically renders a template based on + the current controller and action names. ## Arguments - * `conn` - `Plug.Conn` - * `template_key` - `String` - * `assigns` - `Keyword` - * `opts` - `Keyword` ## Returns @@ -173,23 +170,33 @@ defmodule Sugar.Controller do render_view(conn, template, [], []) end - def render(conn, template, assigns \\ [], opts \\ []) + @doc """ + Sends a normal response. - def render(conn, template, assigns, opts) when is_atom(template) do - template = build_template_key(conn,template) - render_view(conn, template, assigns, opts) - end + ## Arguments - def render(conn, template, assigns, opts) when is_binary(template) do - template = build_template_key(conn,template) + * `conn` - `Plug.Conn` + * `template_key` - `String` + * `assigns` - `Keyword` + * `opts` - `Keyword` + + ## Returns + + `Plug.Conn` + """ + def render(conn, template, assigns \\ [], opts \\ []) + def render(conn, template, assigns, opts) when is_atom(template) + or is_binary(template) do + template = build_template_key(conn, template) render_view(conn, template, assigns, opts) end defp render_view(conn, template_key, assigns, opts) do opts = [status: 200] |> Keyword.merge opts - html = Sugar.Views.Finder.one("lib/#{Mix.Project.config[:app]}/views", template_key) - |> Sugar.Templates.render(assigns) + html = Sugar.Config.get(:sugar, :views_dir, "lib/#{Mix.Project.config[:app]}/views") + |> Sugar.Views.Finder.one(template_key) + |> Sugar.Templates.render(assigns) conn |> put_resp_content_type_if_not_sent(opts[:content_type] || "text/html") @@ -269,10 +276,11 @@ defmodule Sugar.Controller do end defp build_template_key(conn, template \\ nil) do - template = template || conn.private.action + default = Map.get(conn.private, :action) || :index + template = template || default controller = "#{Map.get(conn.private, :controller, "")}" - |> String.split(".") + |> String.split(".") |> List.last |> String.downcase diff --git a/lib/sugar/exceptions.ex b/lib/sugar/exceptions.ex deleted file mode 100644 index ff07889..0000000 --- a/lib/sugar/exceptions.ex +++ /dev/null @@ -1,278 +0,0 @@ -# Sugar's Dev Exception screen is based off of Phalcon's Debug screen. -# Below is the original license and header for the corresponding file -# in the cphalcon project: -# -# License: -# -# New BSD License -# -# Copyright (c) 2011-2014, Phalcon Framework Team -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Header: -# +------------------------------------------------------------------------+ -# | Phalcon Framework | -# +------------------------------------------------------------------------+ -# | Copyright (c) 2011-2014 Phalcon Team (http://www.phalconphp.com) | -# +------------------------------------------------------------------------+ -# | This source file is subject to the New BSD License that is bundled | -# | with this package in the file docs/LICENSE.txt. | -# | | -# | If you did not receive a copy of the license and are unable to | -# | obtain it through the world-wide-web, please send an email | -# | to license@phalconphp.com so we can send you a copy immediately. | -# +------------------------------------------------------------------------+ -# | Authors: Andres Gutierrez | -# | Eduar Carvajal | -# +------------------------------------------------------------------------+ - -defmodule Sugar.Exceptions do - def dev_template do - """ - - - - - - <%= @kind %>: <%= if is_atom(@kind) do %><%= inspect(@value) %><% else %><%= @value.message %><% end %> - - - - -
Sugar Framework 0.4.0-dev
-
-
-

<%= @kind %>: <%= if is_atom(@kind) do %><%= inspect(@value) %><% else %><%= @value.message %><% end %>

- <% file = @stacktrace |> hd %> - <%= file[:file] %> (<%= file[:line] %>) -
-
-
- -
- - - <%= for st <- @stacktrace do %> - - - - - <% end %> -
# - <%= st[:module] %>.<%= st[:function] %>/<%= st[:arrity] %> -
-
- <%= st[:file] %> (<%= st[:line] %>) -
-
<%= st[:source] %>
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyValue
adapter<%= inspect(@conn.adapter) %>
assigns<%= inspect(@conn.assigns) %>
before_send<%= inspect(@conn.before_send) %>
cookies<%= inspect(@conn.cookies) %>
host<%= inspect(@conn.host) %>
method<%= inspect(@conn.method) %>
params<%= inspect(@conn.params) %>
path_info<%= inspect(@conn.path_info) %>
port<%= inspect(@conn.port) %>
private<%= inspect(@conn.private) %>
query_string<%= inspect(@conn.query_string) %>
req_cookies<%= inspect(@conn.req_cookies) %>
req_headers - - <%= for {header, value} <- @conn.req_headers do %> - - - - - <% end %> -
<%= header %><%= value %>
-
resp_body<%= inspect(@conn.resp_body) %>
resp_cookies<%= inspect(@conn.resp_cookies) %>
resp_headers<%= inspect(@conn.resp_headers) %>
scheme<%= inspect(@conn.scheme) %>
script_name<%= inspect(@conn.script_name) %>
state<%= inspect(@conn.state) %>
status<%= inspect(@conn.status) %>
-
-
- - - - - - <%= for var <- @env do %> - - - - - <% end %> -
KeyValue
<%= var[:key] %><%= var[:value] %>
-
-
- - - - - - - - - - - - - -
Version<%= @elixir_build_info[:version] %>
Tag<%= @elixir_build_info[:tag] %>
Build Date<%= @elixir_build_info[:date] %>
-
-
- - - - - -
-
- - - """ - end -end diff --git a/lib/sugar/router.ex b/lib/sugar/router.ex index dc6b681..00b3444 100644 --- a/lib/sugar/router.ex +++ b/lib/sugar/router.ex @@ -280,9 +280,9 @@ defmodule Sugar.Router do binding = binding() conn = var!(conn) - conn = update_in conn.private, - &(&1 |> Map.put(:controller, unquote(controller)) - |> Map.put(:action, unquote(action))) + conn = %{ conn | private: conn.private + |> Map.put(:controller, unquote(controller)) + |> Map.put(:action, unquote(action)) } # pass off to controller action call_controller_action conn, unquote(controller), unquote(action), binding diff --git a/mix.exs b/mix.exs index 1f5cf7f..4b40429 100644 --- a/mix.exs +++ b/mix.exs @@ -20,7 +20,7 @@ defmodule Sugar.Mixfile do defp deps(:prod) do [ { :cowboy, "~> 1.0.0" }, - { :plug, "~> 0.7.0" }, + { :plug, "~> 0.7.0", override: true }, { :jsex, "~> 2.0.0" }, { :ecto, "~> 0.2.5" }, { :postgrex, "~> 0.6.0" }, diff --git a/test/fixtures/templates/foo/index.html.eex b/test/fixtures/templates/foo/index.html.eex new file mode 100644 index 0000000..e69de29 diff --git a/test/fixtures/templates/index.html.eex b/test/fixtures/templates/index.html.eex new file mode 100644 index 0000000..e69de29 diff --git a/test/sugar/app_test.exs b/test/sugar/app_test.exs index fd83f7f..4626cd2 100644 --- a/test/sugar/app_test.exs +++ b/test/sugar/app_test.exs @@ -26,10 +26,6 @@ defmodule Sugar.AppTest do assert get_port([port: 8888]) === 8888 assert get_port([port: -8888]) === 8888 end - - test "config/0" do - assert config === [] - end end defmodule Router do diff --git a/test/sugar/config_test.exs b/test/sugar/config_test.exs new file mode 100644 index 0000000..a9d049e --- /dev/null +++ b/test/sugar/config_test.exs @@ -0,0 +1,17 @@ +defmodule Sugar.ConfigTest do + use ExUnit.Case, async: true + import Sugar.Config + + test "get/1" do + assert get(:router) === nil + end + + test "get/2" do + assert get(Router, :https_only) === nil + end + + test "get/3" do + assert get(:sugar, :router, Router) === Router + assert get(Router, :https_only, false) === false + end +end diff --git a/test/sugar/controller_test.exs b/test/sugar/controller_test.exs index 79a63f8..87efe58 100644 --- a/test/sugar/controller_test.exs +++ b/test/sugar/controller_test.exs @@ -69,49 +69,49 @@ defmodule Sugar.ControllerTest do assert conn.state === :sent end + test "render/1" do + conn = conn(:get, "/") + |> Map.put(:state, :set) + |> render + + assert conn.state === :sent + assert get_resp_header(conn, "content-type") === ["text/html; charset=utf-8"] + end + test "render/4 without assigns and opts" do - build_template conn = conn(:get, "/") |> Map.put(:state, :set) - |> render("index.html.eex") + |> render("foo/index.html.eex") assert conn.state === :sent assert get_resp_header(conn, "content-type") === ["text/html; charset=utf-8"] - destroy_template end test "render/4 with assigns and without opts" do - build_template conn = conn(:get, "/") |> Map.put(:state, :set) - |> render("index.html.eex", []) + |> render("foo/index.html.eex", []) assert conn.state === :sent assert get_resp_header(conn, "content-type") === ["text/html; charset=utf-8"] - destroy_template end test "render/4 with assigns and opts" do - build_template conn = conn(:get, "/") |> Map.put(:state, :set) - |> render("index.html.eex", [], [content_type: "text/html"]) + |> render("foo/index.html.eex", [], [content_type: "text/html"]) assert conn.state === :sent assert get_resp_header(conn, "content-type") === ["text/html; charset=utf-8"] - destroy_template end test "render/4 with a symbol" do - File.mkdir("lib/sugar/views/tests/") - File.touch("lib/sugar/views/tests/index.html.eex") conn = conn(:get, "/") |> Map.put(:state, :set) - |> render("tests/index.html.eex", [], [content_type: "text/html"]) + |> render("foo/index.html.eex", [], [content_type: "text/html"]) assert conn.state === :sent assert get_resp_header(conn, "content-type") === ["text/html; charset=utf-8"] - File.rm!("lib/sugar/views/tests/index.html.eex") end test "halt!/2 without opts" do @@ -193,14 +193,6 @@ defmodule Sugar.ControllerTest do assert conn.state === :sent end - defp build_template do - File.write!("lib/sugar/views/index.html.eex", "") - end - - defp destroy_template do - File.rm!("lib/sugar/views/index.html.eex") - end - defmodule Controller do def create(conn, _args) do halt! conn, [status: 204, message: "Created"] diff --git a/test/sugar/exceptions_test.exs b/test/sugar/exceptions_test.exs deleted file mode 100644 index 08880f7..0000000 --- a/test/sugar/exceptions_test.exs +++ /dev/null @@ -1,27 +0,0 @@ -defmodule Sugar.ExceptionsTest do - use ExUnit.Case - use Plug.Test - - test "init/1" do - assert Sugar.Plugs.Exceptions.init(opts) === opts - end - - test "call/2 with no error" do - conn = conn(:get, "/") - |> Sugar.Plugs.Exceptions.call(opts) - - # assert conn.status === 200 - assert conn.resp_body === nil - end - - test "call/2 with error" do - conn = conn(:get, "/") |> Sugar.Plugs.Exceptions.call(opts) - - # assert conn.status == 500 - refute conn.resp_body === "" - end - - defp opts do - [dev_template: ""] - end -end