Skip to content

Commit

Permalink
Drop support for local middleware/adapter functions #171
Browse files Browse the repository at this point in the history
  • Loading branch information
teamon committed Feb 16, 2018
1 parent 3be359b commit 377798d
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 109 deletions.
2 changes: 1 addition & 1 deletion lib/tesla.ex
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ defmodule Tesla do
def new(token) do
Tesla.build_client([
{Tesla.Middleware.Headers, %{"Authorization" => token}}
{Tesla.Middleware.Headers, [{"authorization", token}]
])
end
end
Expand Down
25 changes: 4 additions & 21 deletions lib/tesla/builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,12 @@ defmodule Tesla.Builder do
# plug middleware module with options
plug Tesla.Middleware.BaseUrl, "http://api.example.com"
plug Tesla.Middleware.JSON, engine: Poison
# plug middleware function
plug :handle_errors
# or without options
plug Tesla.Middleware.JSON
# middleware function gets two parameters: Tesla.Env and the rest of middleware call stack
# and must return Tesla.Env
def handle_errors(env, next) do
env
|> modify_env_before_request
|> Tesla.run(next) # run the rest of stack
|> modify_env_after_request
end
# or a custom middleware
plug MyProject.CustomMiddleware
end
"""

Expand Down Expand Up @@ -126,20 +119,11 @@ defmodule Tesla.Builder do
# set adapter as module
adapter Tesla.Adapter.Hackney
# set adapter as function
adapter :local_adapter
# set adapter as anonymous function
adapter fn env ->
...
env
end
# adapter function gets Tesla.Env as parameter and must return Tesla.Env
def local_adapter(env) do
...
env
end
end
"""
defmacro adapter(name, opts) do
Expand Down Expand Up @@ -381,7 +365,6 @@ defmodule Tesla.Builder do
# :local_middleware
defp compile({name, {kind, caller}}) when is_atom(name) do
Tesla.Migration.breaking_alias!(kind, name, caller)
quote do: {__MODULE__, unquote(name), []}
end

defp compile_context(list, context) do
Expand Down
25 changes: 9 additions & 16 deletions lib/tesla/migration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,20 @@ defmodule Tesla.Migration do
def breaking_alias!(_kind, _name, nil), do: nil

def breaking_alias!(kind, name, caller) do
arity = local_function_arity(kind)

unless Module.defines?(caller.module, {name, arity}) do
raise CompileError,
file: caller.file,
line: caller.line,
description: """
raise CompileError,
file: caller.file,
line: caller.line,
description: """
#{kind |> to_string |> String.capitalize()} aliases has been removed.
Use full #{kind} name or define a local function #{name}/#{arity}
#{kind |> to_string |> String.capitalize()} aliases and local functions has been removed.
Use full #{kind} name or define a middleware module #{name |> to_string() |> String.capitalize()}
#{snippet(caller)}
#{snippet(caller)}
See #{@breaking_alias}
"""
end
See #{@breaking_alias}
"""
end

defp local_function_arity(:adapter), do: 1
defp local_function_arity(:middleware), do: 2

def breaking_alias_in_config!(module) do
check_config(
Application.get_env(:tesla, module, [])[:adapter],
Expand Down
40 changes: 22 additions & 18 deletions test/tesla/0.x_to_1.0_migration_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,18 @@ defmodule MigrationTest do
end
end

test "no error when using atom as plug and there is a local function with that name" do
Code.compile_quoted(
quote do
defmodule Client2 do
use Tesla
plug :json
def json(env, next), do: Tesla.run(env, next)
test "compile error when using atom as plug even if there is a local function with that name" do
assert_raise CompileError, fn ->
Code.compile_quoted(
quote do
defmodule Client2 do
use Tesla
plug :json
def json(env, next), do: Tesla.run(env, next)
end
end
end
)
)
end
end

test "compile error when using atom as adapter" do
Expand Down Expand Up @@ -53,16 +55,18 @@ defmodule MigrationTest do
end
end

test "no error when using atom as adapter and there is a local function with that name" do
Code.compile_quoted(
quote do
defmodule Client5 do
use Tesla
adapter :local
def local(env), do: env
test "compile error when using atom as adapter even if there is a local function with that name" do
assert_raise CompileError, fn ->
Code.compile_quoted(
quote do
defmodule Client5 do
use Tesla
adapter :local
def local(env), do: env
end
end
end
)
)
end
end

test "compile error when using atom as adapter in config" do
Expand Down
17 changes: 0 additions & 17 deletions test/tesla/builder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,13 @@ defmodule Tesla.BuilderTest do
plug FirstMiddleware, @attr
plug SecondMiddleware, options: :are, fun: 1
plug ThirdMiddleware
plug :local_middleware
plug fn env, _next -> env end

def local_middleware(env, next), do: Tesla.run(env, next)

def new do
Tesla.Builder.client(
[
FirstMiddleware,
{SecondMiddleware, options: :are, fun: 1},
:local_middleware,
fn env, _next -> env end
],
[]
Expand All @@ -35,13 +31,6 @@ defmodule Tesla.BuilderTest do
adapter TheAdapter, hello: "world"
end

defmodule TestClientFunction do
use Tesla.Builder
adapter :local_adapter

def local_adapter(env), do: env
end

defmodule TestClientAnon do
use Tesla.Builder
adapter fn env -> env end
Expand All @@ -52,7 +41,6 @@ defmodule Tesla.BuilderTest do
{FirstMiddleware, :call, ["value"]},
{SecondMiddleware, :call, [[options: :are, fun: 1]]},
{ThirdMiddleware, :call, [nil]},
{TestClientPlug, :local_middleware, []},
{:fn, fun}
] = TestClientPlug.__middleware__()

Expand All @@ -67,10 +55,6 @@ defmodule Tesla.BuilderTest do
assert TestClientModule.__adapter__() == {TheAdapter, :call, [[hello: "world"]]}
end

test "generate __adapter__/0 - adapter as module function" do
assert TestClientFunction.__adapter__() == {TestClientFunction, :local_adapter, []}
end

test "generate __adapter__/0 - adapter as anonymous function" do
assert {:fn, fun} = TestClientAnon.__adapter__()
assert is_function(fun)
Expand All @@ -82,7 +66,6 @@ defmodule Tesla.BuilderTest do
assert [
{FirstMiddleware, :call, [nil]},
{SecondMiddleware, :call, [[options: :are, fun: 1]]},
{TestClientPlug, :local_middleware, []},
{:fn, fun}
] = client.pre

Expand Down
14 changes: 8 additions & 6 deletions test/tesla/middleware/fuse_test.exs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
defmodule Tesla.Middleware.FuseTest do
use ExUnit.Case, async: false

defmodule Report do
def call(env, next, _) do
send(self(), :request_made)
Tesla.run(env, next)
end
end

defmodule Client do
use Tesla

plug Tesla.Middleware.Fuse
plug :report

def report(env, next) do
send(self(), :request_made)
Tesla.run(env, next)
end
plug Report

adapter fn env ->
case env.url do
Expand Down
31 changes: 1 addition & 30 deletions test/tesla_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,6 @@ defmodule TeslaTest do
adapter ModuleAdapter, with: "someopt"
end

defmodule LocalAdapterClient do
use Tesla

adapter :local_adapter

def local_adapter(env) do
{:ok, Map.put(env, :url, env.url <> "/local")}
end
end

defmodule FunAdapterClient do
use Tesla

Expand Down Expand Up @@ -66,11 +56,6 @@ defmodule TeslaTest do
assert response.url == "test/module/someopt"
end

test "execute local function adapter" do
assert {:ok, response} = LocalAdapterClient.request(url: "test")
assert response.url == "test/local"
end

test "execute anonymous function adapter" do
assert {:ok, response} = FunAdapterClient.request(url: "test")
assert response.url == "test/anon"
Expand Down Expand Up @@ -111,27 +96,13 @@ defmodule TeslaTest do
plug AppendOne
plug AppendWith, with: "1"
plug AppendWith, with: "2"
plug :local_middleware

adapter fn env -> {:ok, env} end

def local_middleware(env, next) do
env
|> Map.update!(:url, fn url -> url <> "/LB" end)
|> Tesla.run(next)
|> case do
{:ok, env} ->
{:ok, Map.update!(env, :url, fn url -> url <> "/LA" end)}

error ->
error
end
end
end

test "execute middleware top down" do
assert {:ok, response} = AppendClient.get("one")
assert response.url == "one/1/MB1/MB2/LB/LA/MA2/MA1"
assert response.url == "one/1/MB1/MB2/MA2/MA1"
end
end

Expand Down

0 comments on commit 377798d

Please sign in to comment.