summaryrefslogtreecommitdiff
path: root/src/etap
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2010-08-11 15:41:54 -0400
committerAdam Kocoloski <adam@cloudant.com>2010-08-11 17:39:37 -0400
commitf3d13cdfeeaf1f4c0dd938bdee455b0812678eb0 (patch)
tree092fc4acf2b5fb7bef48ffee260de2fa4db6446a /src/etap
parent8138d70bb8c1de954c46b417ccd22964b6432965 (diff)
move etap to rebar layout and add simple .app template
Diffstat (limited to 'src/etap')
-rw-r--r--src/etap/etap.erl416
-rw-r--r--src/etap/etap_application.erl72
-rw-r--r--src/etap/etap_can.erl79
-rw-r--r--src/etap/etap_exception.erl66
-rw-r--r--src/etap/etap_process.erl42
-rw-r--r--src/etap/etap_report.erl343
-rw-r--r--src/etap/etap_request.erl89
-rw-r--r--src/etap/etap_string.erl47
-rw-r--r--src/etap/etap_web.erl65
9 files changed, 0 insertions, 1219 deletions
diff --git a/src/etap/etap.erl b/src/etap/etap.erl
deleted file mode 100644
index 5ad5dba3..00000000
--- a/src/etap/etap.erl
+++ /dev/null
@@ -1,416 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @author Nick Gerakines <nick@gerakines.net> [http://socklabs.com/]
-%% @author Jeremy Wall <jeremy@marzhillstudios.com>
-%% @version 0.3.4
-%% @copyright 2007-2008 Jeremy Wall, 2008-2009 Nick Gerakines
-%% @reference http://testanything.org/wiki/index.php/Main_Page
-%% @reference http://en.wikipedia.org/wiki/Test_Anything_Protocol
-%% @todo Finish implementing the skip directive.
-%% @todo Document the messages handled by this receive loop.
-%% @todo Explain in documentation why we use a process to handle test input.
-%% @doc etap is a TAP testing module for Erlang components and applications.
-%% This module allows developers to test their software using the TAP method.
-%%
-%% <blockquote cite="http://en.wikipedia.org/wiki/Test_Anything_Protocol"><p>
-%% TAP, the Test Anything Protocol, is a simple text-based interface between
-%% testing modules in a test harness. TAP started life as part of the test
-%% harness for Perl but now has implementations in C/C++, Python, PHP, Perl
-%% and probably others by the time you read this.
-%% </p></blockquote>
-%%
-%% The testing process begins by defining a plan using etap:plan/1, running
-%% a number of etap tests and then calling eta:end_tests/0. Please refer to
-%% the Erlang modules in the t directory of this project for example tests.
--module(etap).
--export([
- ensure_test_server/0, start_etap_server/0, test_server/1,
- diag/1, diag/2, plan/1, end_tests/0, not_ok/2, ok/2, is/3, isnt/3,
- any/3, none/3, fun_is/3, is_greater/3, skip/1, skip/2,
- ensure_coverage_starts/0, ensure_coverage_ends/0, coverage_report/0,
- datetime/1, skip/3, bail/0, bail/1
-]).
--record(test_state, {planned = 0, count = 0, pass = 0, fail = 0, skip = 0, skip_reason = ""}).
--vsn("0.3.4").
-
-%% @spec plan(N) -> Result
-%% N = unknown | skip | {skip, string()} | integer()
-%% Result = ok
-%% @doc Create a test plan and boot strap the test server.
-plan(unknown) ->
- ensure_coverage_starts(),
- ensure_test_server(),
- etap_server ! {self(), plan, unknown},
- ok;
-plan(skip) ->
- io:format("1..0 # skip~n");
-plan({skip, Reason}) ->
- io:format("1..0 # skip ~s~n", [Reason]);
-plan(N) when is_integer(N), N > 0 ->
- ensure_coverage_starts(),
- ensure_test_server(),
- etap_server ! {self(), plan, N},
- ok.
-
-%% @spec end_tests() -> ok
-%% @doc End the current test plan and output test results.
-%% @todo This should probably be done in the test_server process.
-end_tests() ->
- ensure_coverage_ends(),
- etap_server ! {self(), state},
- State = receive X -> X end,
- if
- State#test_state.planned == -1 ->
- io:format("1..~p~n", [State#test_state.count]);
- true ->
- ok
- end,
- case whereis(etap_server) of
- undefined -> ok;
- _ -> etap_server ! done, ok
- end.
-
-%% @private
-ensure_coverage_starts() ->
- case os:getenv("COVER") of
- false -> ok;
- _ ->
- BeamDir = case os:getenv("COVER_BIN") of false -> "ebin"; X -> X end,
- cover:compile_beam_directory(BeamDir)
- end.
-
-%% @private
-%% @doc Attempts to write out any collected coverage data to the cover/
-%% directory. This function should not be called externally, but it could be.
-ensure_coverage_ends() ->
- case os:getenv("COVER") of
- false -> ok;
- _ ->
- filelib:ensure_dir("cover/"),
- Name = lists:flatten([
- io_lib:format("~.16b", [X]) || X <- binary_to_list(erlang:md5(
- term_to_binary({make_ref(), now()})
- ))
- ]),
- cover:export("cover/" ++ Name ++ ".coverdata")
- end.
-
-%% @spec coverage_report() -> ok
-%% @doc Use the cover module's covreage report builder to create code coverage
-%% reports from recently created coverdata files.
-coverage_report() ->
- [cover:import(File) || File <- filelib:wildcard("cover/*.coverdata")],
- lists:foreach(
- fun(Mod) ->
- cover:analyse_to_file(Mod, atom_to_list(Mod) ++ "_coverage.txt", [])
- end,
- cover:imported_modules()
- ),
- ok.
-
-bail() ->
- bail("").
-
-bail(Reason) ->
- etap_server ! {self(), diag, "Bail out! " ++ Reason},
- ensure_coverage_ends(),
- etap_server ! done, ok,
- ok.
-
-
-%% @spec diag(S) -> ok
-%% S = string()
-%% @doc Print a debug/status message related to the test suite.
-diag(S) -> etap_server ! {self(), diag, "# " ++ S}, ok.
-
-%% @spec diag(Format, Data) -> ok
-%% Format = atom() | string() | binary()
-%% Data = [term()]
-%% UnicodeList = [Unicode]
-%% Unicode = int()
-%% @doc Print a debug/status message related to the test suite.
-%% Function arguments are passed through io_lib:format/2.
-diag(Format, Data) -> diag(io_lib:format(Format, Data)).
-
-%% @spec ok(Expr, Desc) -> Result
-%% Expr = true | false
-%% Desc = string()
-%% Result = true | false
-%% @doc Assert that a statement is true.
-ok(Expr, Desc) -> mk_tap(Expr == true, Desc).
-
-%% @spec not_ok(Expr, Desc) -> Result
-%% Expr = true | false
-%% Desc = string()
-%% Result = true | false
-%% @doc Assert that a statement is false.
-not_ok(Expr, Desc) -> mk_tap(Expr == false, Desc).
-
-%% @spec is(Got, Expected, Desc) -> Result
-%% Got = any()
-%% Expected = any()
-%% Desc = string()
-%% Result = true | false
-%% @doc Assert that two values are the same.
-is(Got, Expected, Desc) ->
- case mk_tap(Got == Expected, Desc) of
- false ->
- etap_server ! {self(), diag, " ---"},
- etap_server ! {self(), diag, io_lib:format(" description: ~p", [Desc])},
- etap_server ! {self(), diag, io_lib:format(" found: ~p", [Got])},
- etap_server ! {self(), diag, io_lib:format(" wanted: ~p", [Expected])},
- etap_server ! {self(), diag, " ..."},
- false;
- true -> true
- end.
-
-%% @spec isnt(Got, Expected, Desc) -> Result
-%% Got = any()
-%% Expected = any()
-%% Desc = string()
-%% Result = true | false
-%% @doc Assert that two values are not the same.
-isnt(Got, Expected, Desc) -> mk_tap(Got /= Expected, Desc).
-
-%% @spec is_greater(ValueA, ValueB, Desc) -> Result
-%% ValueA = number()
-%% ValueB = number()
-%% Desc = string()
-%% Result = true | false
-%% @doc Assert that an integer is greater than another.
-is_greater(ValueA, ValueB, Desc) when is_integer(ValueA), is_integer(ValueB) ->
- mk_tap(ValueA > ValueB, Desc).
-
-%% @spec any(Got, Items, Desc) -> Result
-%% Got = any()
-%% Items = [any()]
-%% Desc = string()
-%% Result = true | false
-%% @doc Assert that an item is in a list.
-any(Got, Items, Desc) ->
- is(lists:member(Got, Items), true, Desc).
-
-%% @spec none(Got, Items, Desc) -> Result
-%% Got = any()
-%% Items = [any()]
-%% Desc = string()
-%% Result = true | false
-%% @doc Assert that an item is not in a list.
-none(Got, Items, Desc) ->
- is(lists:member(Got, Items), false, Desc).
-
-%% @spec fun_is(Fun, Expected, Desc) -> Result
-%% Fun = function()
-%% Expected = any()
-%% Desc = string()
-%% Result = true | false
-%% @doc Use an anonymous function to assert a pattern match.
-fun_is(Fun, Expected, Desc) when is_function(Fun) ->
- is(Fun(Expected), true, Desc).
-
-%% @equiv skip(TestFun, "")
-skip(TestFun) when is_function(TestFun) ->
- skip(TestFun, "").
-
-%% @spec skip(TestFun, Reason) -> ok
-%% TestFun = function()
-%% Reason = string()
-%% @doc Skip a test.
-skip(TestFun, Reason) when is_function(TestFun), is_list(Reason) ->
- begin_skip(Reason),
- catch TestFun(),
- end_skip(),
- ok.
-
-%% @spec skip(Q, TestFun, Reason) -> ok
-%% Q = true | false | function()
-%% TestFun = function()
-%% Reason = string()
-%% @doc Skips a test conditionally. The first argument to this function can
-%% either be the 'true' or 'false' atoms or a function that returns 'true' or
-%% 'false'.
-skip(QFun, TestFun, Reason) when is_function(QFun), is_function(TestFun), is_list(Reason) ->
- case QFun() of
- true -> begin_skip(Reason), TestFun(), end_skip();
- _ -> TestFun()
- end,
- ok;
-
-skip(Q, TestFun, Reason) when is_function(TestFun), is_list(Reason), Q == true ->
- begin_skip(Reason),
- TestFun(),
- end_skip(),
- ok;
-
-skip(_, TestFun, Reason) when is_function(TestFun), is_list(Reason) ->
- TestFun(),
- ok.
-
-%% @private
-begin_skip(Reason) ->
- etap_server ! {self(), begin_skip, Reason}.
-
-%% @private
-end_skip() ->
- etap_server ! {self(), end_skip}.
-
-% ---
-% Internal / Private functions
-
-%% @private
-%% @doc Start the etap_server process if it is not running already.
-ensure_test_server() ->
- case whereis(etap_server) of
- undefined ->
- proc_lib:start(?MODULE, start_etap_server,[]);
- _ ->
- diag("The test server is already running.")
- end.
-
-%% @private
-%% @doc Start the etap_server loop and register itself as the etap_server
-%% process.
-start_etap_server() ->
- catch register(etap_server, self()),
- proc_lib:init_ack(ok),
- etap:test_server(#test_state{
- planned = 0,
- count = 0,
- pass = 0,
- fail = 0,
- skip = 0,
- skip_reason = ""
- }).
-
-
-%% @private
-%% @doc The main etap_server receive/run loop. The etap_server receive loop
-%% responds to seven messages apperatining to failure or passing of tests.
-%% It is also used to initiate the testing process with the {_, plan, _}
-%% message that clears the current test state.
-test_server(State) ->
- NewState = receive
- {_From, plan, unknown} ->
- io:format("# Current time local ~s~n", [datetime(erlang:localtime())]),
- io:format("# Using etap version ~p~n", [ proplists:get_value(vsn, proplists:get_value(attributes, etap:module_info())) ]),
- State#test_state{
- planned = -1,
- count = 0,
- pass = 0,
- fail = 0,
- skip = 0,
- skip_reason = ""
- };
- {_From, plan, N} ->
- io:format("# Current time local ~s~n", [datetime(erlang:localtime())]),
- io:format("# Using etap version ~p~n", [ proplists:get_value(vsn, proplists:get_value(attributes, etap:module_info())) ]),
- io:format("1..~p~n", [N]),
- State#test_state{
- planned = N,
- count = 0,
- pass = 0,
- fail = 0,
- skip = 0,
- skip_reason = ""
- };
- {_From, begin_skip, Reason} ->
- State#test_state{
- skip = 1,
- skip_reason = Reason
- };
- {_From, end_skip} ->
- State#test_state{
- skip = 0,
- skip_reason = ""
- };
- {_From, pass, Desc} ->
- FullMessage = skip_diag(
- " - " ++ Desc,
- State#test_state.skip,
- State#test_state.skip_reason
- ),
- io:format("ok ~p ~s~n", [State#test_state.count + 1, FullMessage]),
- State#test_state{
- count = State#test_state.count + 1,
- pass = State#test_state.pass + 1
- };
-
- {_From, fail, Desc} ->
- FullMessage = skip_diag(
- " - " ++ Desc,
- State#test_state.skip,
- State#test_state.skip_reason
- ),
- io:format("not ok ~p ~s~n", [State#test_state.count + 1, FullMessage]),
- State#test_state{
- count = State#test_state.count + 1,
- fail = State#test_state.fail + 1
- };
- {From, state} ->
- From ! State,
- State;
- {_From, diag, Message} ->
- io:format("~s~n", [Message]),
- State;
- {From, count} ->
- From ! State#test_state.count,
- State;
- {From, is_skip} ->
- From ! State#test_state.skip,
- State;
- done ->
- exit(normal)
- end,
- test_server(NewState).
-
-%% @private
-%% @doc Process the result of a test and send it to the etap_server process.
-mk_tap(Result, Desc) ->
- IsSkip = lib:sendw(etap_server, is_skip),
- case [IsSkip, Result] of
- [_, true] ->
- etap_server ! {self(), pass, Desc},
- true;
- [1, _] ->
- etap_server ! {self(), pass, Desc},
- true;
- _ ->
- etap_server ! {self(), fail, Desc},
- false
- end.
-
-%% @private
-%% @doc Format a date/time string.
-datetime(DateTime) ->
- {{Year, Month, Day}, {Hour, Min, Sec}} = DateTime,
- io_lib:format("~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B", [Year, Month, Day, Hour, Min, Sec]).
-
-%% @private
-%% @doc Craft an output message taking skip/todo into consideration.
-skip_diag(Message, 0, _) ->
- Message;
-skip_diag(_Message, 1, "") ->
- " # SKIP";
-skip_diag(_Message, 1, Reason) ->
- " # SKIP : " ++ Reason.
diff --git a/src/etap/etap_application.erl b/src/etap/etap_application.erl
deleted file mode 100644
index 98b52751..00000000
--- a/src/etap/etap_application.erl
+++ /dev/null
@@ -1,72 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @author Nick Gerakines <nick@gerakines.net> [http://socklabs.com/]
-%% @copyright 2008 Nick Gerakines
-%% @reference http://testanything.org/wiki/index.php/Main_Page
-%% @reference http://en.wikipedia.org/wiki/Test_Anything_Protocol
-%% @todo Explain in documentation why we use a process to handle test input.
-%% @todo Add test to verify the number of members in a pg2 group.
-%% @doc Provide test functionality to the application and related behaviors.
--module(etap_application).
--export([
- start_ok/2, ensure_loaded/3, load_ok/2,
- pg2_group_exists/2, pg2_group_doesntexist/2
-]).
-
-%% @spec load_ok(string(), string()) -> true | false
-%% @doc Assert that an application can be loaded successfully.
-load_ok(AppName, Desc) ->
- etap:ok(application:load(AppName) == ok, Desc).
-
-%% @spec start_ok(string(), string()) -> true | false
-%% @doc Assert that an application can be started successfully.
-start_ok(AppName, Desc) ->
- etap:ok(application:start(AppName) == ok, Desc).
-
-%% @spec ensure_loaded(string(), string(), string()) -> true | false
-%% @doc Assert that an application has been loaded successfully.
-ensure_loaded(AppName, AppVsn, Desc) ->
- etap:any(
- fun(Match) -> case Match of {AppName, _, AppVsn} -> true; _ -> false end end,
- application:loaded_applications(),
- Desc
- ).
-
-%% @spec pg2_group_exists(string(), string()) -> true | false
-%% @doc Assert that a pg2 group exists.
-pg2_group_exists(GroupName, Desc) ->
- etap:any(
- fun(Match) -> Match == GroupName end,
- pg2:which_groups(),
- Desc
- ).
-
-%% @spec pg2_group_doesntexist(string(), string()) -> true | false
-%% @doc Assert that a pg2 group does not exists.
-pg2_group_doesntexist(GroupName, Desc) ->
- etap:none(
- fun(Match) -> Match == GroupName end,
- pg2:which_groups(),
- Desc
- ).
diff --git a/src/etap/etap_can.erl b/src/etap/etap_can.erl
deleted file mode 100644
index 552b7174..00000000
--- a/src/etap/etap_can.erl
+++ /dev/null
@@ -1,79 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @reference http://testanything.org/wiki/index.php/Main_Page
-%% @reference http://en.wikipedia.org/wiki/Test_Anything_Protocol
-%% @doc Provide test functionality modules
--module(etap_can).
-
--export([
- loaded_ok/2, can_ok/2, can_ok/3,
- has_attrib/2, is_attrib/3, is_behaviour/2
-]).
-
-%% @spec loaded_ok(atom(), string()) -> true | false
-%% @doc Assert that a module has been loaded successfully.
-loaded_ok(M, Desc) when is_atom(M) ->
- etap:fun_is(fun({module, _}) -> true; (_) -> false end, code:load_file(M), Desc).
-
-%% @spec can_ok(atom(), atom()) -> true | false
-%% @doc Assert that a module exports a given function.
-can_ok(M, F) when is_atom(M), is_atom(F) ->
- Matches = [X || {X, _} <- M:module_info(exports), X == F],
- etap:ok(Matches > 0, lists:concat([M, " can ", F])).
-
-%% @spec can_ok(atom(), atom(), integer()) -> true | false
-%% @doc Assert that a module exports a given function with a given arity.
-can_ok(M, F, A) when is_atom(M); is_atom(F), is_number(A) ->
- Matches = [X || X <- M:module_info(exports), X == {F, A}],
- etap:ok(Matches > 0, lists:concat([M, " can ", F, "/", A])).
-
-%% @spec has_attrib(M, A) -> true | false
-%% M = atom()
-%% A = atom()
-%% @doc Asserts that a module has a given attribute.
-has_attrib(M, A) when is_atom(M), is_atom(A) ->
- etap:isnt(
- proplists:get_value(A, M:module_info(attributes), 'asdlkjasdlkads'),
- 'asdlkjasdlkads',
- lists:concat([M, " has attribute ", A])
- ).
-
-%% @spec has_attrib(M, A. V) -> true | false
-%% M = atom()
-%% A = atom()
-%% V = any()
-%% @doc Asserts that a module has a given attribute with a given value.
-is_attrib(M, A, V) when is_atom(M) andalso is_atom(A) ->
- etap:is(
- proplists:get_value(A, M:module_info(attributes)),
- [V],
- lists:concat([M, "'s ", A, " is ", V])
- ).
-
-%% @spec is_behavior(M, B) -> true | false
-%% M = atom()
-%% B = atom()
-%% @doc Asserts that a given module has a specific behavior.
-is_behaviour(M, B) when is_atom(M) andalso is_atom(B) ->
- is_attrib(M, behaviour, B).
diff --git a/src/etap/etap_exception.erl b/src/etap/etap_exception.erl
deleted file mode 100644
index ba660727..00000000
--- a/src/etap/etap_exception.erl
+++ /dev/null
@@ -1,66 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @reference http://testanything.org/wiki/index.php/Main_Page
-%% @reference http://en.wikipedia.org/wiki/Test_Anything_Protocol
-%% @doc Adds exception based testing to the etap suite.
--module(etap_exception).
-
--export([dies_ok/2, lives_ok/2, throws_ok/3]).
-
-% ---
-% External / Public functions
-
-%% @doc Assert that an exception is raised when running a given function.
-dies_ok(F, Desc) ->
- case (catch F()) of
- {'EXIT', _} -> etap:ok(true, Desc);
- _ -> etap:ok(false, Desc)
- end.
-
-%% @doc Assert that an exception is not raised when running a given function.
-lives_ok(F, Desc) ->
- etap:is(try_this(F), success, Desc).
-
-%% @doc Assert that the exception thrown by a function matches the given exception.
-throws_ok(F, Exception, Desc) ->
- try F() of
- _ -> etap:ok(nok, Desc)
- catch
- _:E ->
- etap:is(E, Exception, Desc)
- end.
-
-% ---
-% Internal / Private functions
-
-%% @private
-%% @doc Run a function and catch any exceptions.
-try_this(F) when is_function(F, 0) ->
- try F() of
- _ -> success
- catch
- throw:E -> {throw, E};
- error:E -> {error, E};
- exit:E -> {exit, E}
- end.
diff --git a/src/etap/etap_process.erl b/src/etap/etap_process.erl
deleted file mode 100644
index 69f5ba00..00000000
--- a/src/etap/etap_process.erl
+++ /dev/null
@@ -1,42 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @doc Adds process/pid testing to the etap suite.
--module(etap_process).
-
--export([is_pid/2, is_alive/2, is_mfa/3]).
-
-% ---
-% External / Public functions
-
-%% @doc Assert that a given variable is a pid.
-is_pid(Pid, Desc) when is_pid(Pid) -> etap:ok(true, Desc);
-is_pid(_, Desc) -> etap:ok(false, Desc).
-
-%% @doc Assert that a given process/pid is alive.
-is_alive(Pid, Desc) ->
- etap:ok(erlang:is_process_alive(Pid), Desc).
-
-%% @doc Assert that the current function of a pid is a given {M, F, A} tuple.
-is_mfa(Pid, MFA, Desc) ->
- etap:is({current_function, MFA}, erlang:process_info(Pid, current_function), Desc).
diff --git a/src/etap/etap_report.erl b/src/etap/etap_report.erl
deleted file mode 100644
index 6d692fb6..00000000
--- a/src/etap/etap_report.erl
+++ /dev/null
@@ -1,343 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @doc A module for creating nice looking code coverage reports.
--module(etap_report).
--export([create/0]).
-
-%% @spec create() -> ok
-%% @doc Create html code coverage reports for each module that code coverage
-%% data exists for.
-create() ->
- [cover:import(File) || File <- filelib:wildcard("cover/*.coverdata")],
- Modules = lists:foldl(
- fun(Module, Acc) ->
- [{Module, file_report(Module)} | Acc]
- end,
- [],
- cover:imported_modules()
- ),
- index(Modules).
-
-%% @private
-index(Modules) ->
- {ok, IndexFD} = file:open("cover/index.html", [write]),
- io:format(IndexFD, "<html><head><style>
- table.percent_graph { height: 12px; border:1px solid #E2E6EF; empty-cells: show; }
- table.percent_graph td.covered { height: 10px; background: #00f000; }
- table.percent_graph td.uncovered { height: 10px; background: #e00000; }
- .odd { background-color: #ddd; }
- .even { background-color: #fff; }
- </style></head>", []),
- io:format(IndexFD, "<body>", []),
- lists:foldl(
- fun({Module, {Good, Bad, Source}}, LastRow) ->
- case {Good + Bad, Source} of
- {0, _} -> LastRow;
- {_, none} -> LastRow;
- _ ->
- CovPer = round((Good / (Good + Bad)) * 100),
- UnCovPer = round((Bad / (Good + Bad)) * 100),
- RowClass = case LastRow of 1 -> "odd"; _ -> "even" end,
- io:format(IndexFD, "<div class=\"~s\">", [RowClass]),
- io:format(IndexFD, "<a href=\"~s\">~s</a>", [atom_to_list(Module) ++ "_report.html", atom_to_list(Module)]),
- io:format(IndexFD, "
- <table cellspacing='0' cellpadding='0' align='right'>
- <tr>
- <td><tt>~p%</tt>&nbsp;</td><td>
- <table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
- <tr><td class='covered' width='~p' /><td class='uncovered' width='~p' /></tr>
- </table>
- </td>
- </tr>
- </table>
- ", [CovPer, CovPer, UnCovPer]),
- io:format(IndexFD, "</div>", []),
- case LastRow of
- 1 -> 0;
- 0 -> 1
- end
- end
- end,
- 0,
- lists:sort(Modules)
- ),
- {TotalGood, TotalBad} = lists:foldl(
- fun({_, {Good, Bad, Source}}, {TGood, TBad}) ->
- case Source of none -> {TGood, TBad}; _ -> {TGood + Good, TBad + Bad} end
- end,
- {0, 0},
- Modules
- ),
- io:format(IndexFD, "<p>Generated on ~s.</p>~n", [etap:datetime({date(), time()})]),
- case TotalGood + TotalBad of
- 0 -> ok;
- _ ->
- TotalCovPer = round((TotalGood / (TotalGood + TotalBad)) * 100),
- TotalUnCovPer = round((TotalBad / (TotalGood + TotalBad)) * 100),
- io:format(IndexFD, "<div>", []),
- io:format(IndexFD, "Total
- <table cellspacing='0' cellpadding='0' align='right'>
- <tr>
- <td><tt>~p%</tt>&nbsp;</td><td>
- <table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
- <tr><td class='covered' width='~p' /><td class='uncovered' width='~p' /></tr>
- </table>
- </td>
- </tr>
- </table>
- ", [TotalCovPer, TotalCovPer, TotalUnCovPer]),
- io:format(IndexFD, "</div>", [])
- end,
- io:format(IndexFD, "</body></html>", []),
- file:close(IndexFD),
- ok.
-
-%% @private
-file_report(Module) ->
- {ok, Data} = cover:analyse(Module, calls, line),
- Source = find_source(Module),
- {Good, Bad} = collect_coverage(Data, {0, 0}),
- case {Source, Good + Bad} of
- {none, _} -> ok;
- {_, 0} -> ok;
- _ ->
- {ok, SourceFD} = file:open(Source, [read]),
- {ok, WriteFD} = file:open("cover/" ++ atom_to_list(Module) ++ "_report.html", [write]),
- io:format(WriteFD, "~s", [header(Module, Good, Bad)]),
- output_lines(Data, WriteFD, SourceFD, 1),
- io:format(WriteFD, "~s", [footer()]),
- file:close(WriteFD),
- file:close(SourceFD),
- ok
- end,
- {Good, Bad, Source}.
-
-%% @private
-collect_coverage([], Acc) -> Acc;
-collect_coverage([{{_, _}, 0} | Data], {Good, Bad}) ->
- collect_coverage(Data, {Good, Bad + 1});
-collect_coverage([_ | Data], {Good, Bad}) ->
- collect_coverage(Data, {Good + 1, Bad}).
-
-%% @private
-output_lines(Data, WriteFD, SourceFD, LineNumber) ->
- {Match, NextData} = datas_match(Data, LineNumber),
- case io:get_line(SourceFD, '') of
- eof -> ok;
- Line = "%% @todo" ++ _ ->
- io:format(WriteFD, "~s", [out_line(LineNumber, highlight, Line)]),
- output_lines(NextData, WriteFD, SourceFD, LineNumber + 1);
- Line = "% " ++ _ ->
- io:format(WriteFD, "~s", [out_line(LineNumber, none, Line)]),
- output_lines(NextData, WriteFD, SourceFD, LineNumber + 1);
- Line ->
- case Match of
- {true, CC} ->
- io:format(WriteFD, "~s", [out_line(LineNumber, CC, Line)]),
- output_lines(NextData, WriteFD, SourceFD, LineNumber + 1);
- false ->
- io:format(WriteFD, "~s", [out_line(LineNumber, none, Line)]),
- output_lines(NextData, WriteFD, SourceFD, LineNumber + 1)
- end
- end.
-
-%% @private
-out_line(Number, none, Line) ->
- PadNu = string:right(integer_to_list(Number), 5, $.),
- io_lib:format("<span class=\"marked\"><a name=\"line~p\"></a>~s ~s</span>", [Number, PadNu, Line]);
-out_line(Number, highlight, Line) ->
- PadNu = string:right(integer_to_list(Number), 5, $.),
- io_lib:format("<span class=\"highlight\"><a name=\"line~p\"></a>~s ~s</span>", [Number, PadNu, Line]);
-out_line(Number, 0, Line) ->
- PadNu = string:right(integer_to_list(Number), 5, $.),
- io_lib:format("<span class=\"uncovered\"><a name=\"line~p\"></a>~s ~s</span>", [Number, PadNu, Line]);
-out_line(Number, _, Line) ->
- PadNu = string:right(integer_to_list(Number), 5, $.),
- io_lib:format("<span class=\"covered\"><a name=\"line~p\"></a>~s ~s</span>", [Number, PadNu, Line]).
-
-%% @private
-datas_match([], _) -> {false, []};
-datas_match([{{_, Line}, CC} | Datas], LineNumber) when Line == LineNumber -> {{true, CC}, Datas};
-datas_match(Data, _) -> {false, Data}.
-
-%% @private
-find_source(Module) when is_atom(Module) ->
- Root = filename:rootname(Module),
- Dir = filename:dirname(Root),
- XDir = case os:getenv("SRC") of false -> "src"; X -> X end,
- find_source([
- filename:join([Dir, Root ++ ".erl"]),
- filename:join([Dir, "..", "src", Root ++ ".erl"]),
- filename:join([Dir, "src", Root ++ ".erl"]),
- filename:join([Dir, "elibs", Root ++ ".erl"]),
- filename:join([Dir, "..", "elibs", Root ++ ".erl"]),
- filename:join([Dir, XDir, Root ++ ".erl"])
- ]);
-find_source([]) -> none;
-find_source([Test | Tests]) ->
- case filelib:is_file(Test) of
- true -> Test;
- false -> find_source(Tests)
- end.
-
-%% @private
-header(Module, Good, Bad) ->
- io:format("Good ~p~n", [Good]),
- io:format("Bad ~p~n", [Bad]),
- CovPer = round((Good / (Good + Bad)) * 100),
- UnCovPer = round((Bad / (Good + Bad)) * 100),
- io:format("CovPer ~p~n", [CovPer]),
- io_lib:format("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
- <html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
- <head>
- <title>~s - C0 code coverage information</title>
- <style type='text/css'>body { background-color: rgb(240, 240, 245); }</style>
- <style type='text/css'>span.marked0 {
- background-color: rgb(185, 210, 200);
- display: block;
- }
- span.marked { display: block; background-color: #ffffff; }
- span.highlight { display: block; background-color: #fff9d7; }
- span.covered { display: block; background-color: #f7f7f7 ; }
- span.uncovered { display: block; background-color: #ffebe8 ; }
- span.overview {
- border-bottom: 1px solid #E2E6EF;
- }
- div.overview {
- border-bottom: 1px solid #E2E6EF;
- }
- body {
- font-family: verdana, arial, helvetica;
- }
- div.footer {
- font-size: 68%;
- margin-top: 1.5em;
- }
- h1, h2, h3, h4, h5, h6 {
- margin-bottom: 0.5em;
- }
- h5 {
- margin-top: 0.5em;
- }
- .hidden {
- display: none;
- }
- div.separator {
- height: 10px;
- }
- table.percent_graph {
- height: 12px;
- border: 1px solid #E2E6EF;
- empty-cells: show;
- }
- table.percent_graph td.covered {
- height: 10px;
- background: #00f000;
- }
- table.percent_graph td.uncovered {
- height: 10px;
- background: #e00000;
- }
- table.percent_graph td.NA {
- height: 10px;
- background: #eaeaea;
- }
- table.report {
- border-collapse: collapse;
- width: 100%;
- }
- table.report td.heading {
- background: #dcecff;
- border: 1px solid #E2E6EF;
- font-weight: bold;
- text-align: center;
- }
- table.report td.heading:hover {
- background: #c0ffc0;
- }
- table.report td.text {
- border: 1px solid #E2E6EF;
- }
- table.report td.value {
- text-align: right;
- border: 1px solid #E2E6EF;
- }
- table.report tr.light {
- background-color: rgb(240, 240, 245);
- }
- table.report tr.dark {
- background-color: rgb(230, 230, 235);
- }
- </style>
- </head>
- <body>
- <h3>C0 code coverage information</h3>
- <p>Generated on ~s with <a href='http://github.com/ngerakines/etap'>etap 0.3.4</a>.
- </p>
- <table class='report'>
- <thead>
- <tr>
- <td class='heading'>Name</td>
- <td class='heading'>Total lines</td>
- <td class='heading'>Lines of code</td>
- <td class='heading'>Total coverage</td>
- <td class='heading'>Code coverage</td>
- </tr>
- </thead>
- <tbody>
- <tr class='light'>
-
- <td>
- <a href='~s'>~s</a>
- </td>
- <td class='value'>
- <tt>??</tt>
- </td>
- <td class='value'>
- <tt>??</tt>
- </td>
- <td class='value'>
- <tt>??</tt>
- </td>
- <td>
- <table cellspacing='0' cellpadding='0' align='right'>
- <tr>
- <td><tt>~p%</tt>&nbsp;</td><td>
- <table cellspacing='0' class='percent_graph' cellpadding='0' width='100'>
- <tr><td class='covered' width='~p' /><td class='uncovered' width='~p' /></tr>
- </table>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- </tbody>
- </table><pre>", [Module, etap:datetime({date(), time()}), atom_to_list(Module) ++ "_report.html", Module, CovPer, CovPer, UnCovPer]).
-
-%% @private
-footer() ->
- "</pre><hr /><p>Generated using <a href='http://github.com/ngerakines/etap'>etap 0.3.4</a>.</p>
- </body>
- </html>
- ".
diff --git a/src/etap/etap_request.erl b/src/etap/etap_request.erl
deleted file mode 100644
index 9fd23aca..00000000
--- a/src/etap/etap_request.erl
+++ /dev/null
@@ -1,89 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @doc Provides test functionality against a specific web request. Many of
-%% the exported methods can be used to build your own more complex tests.
--module(etap_request, [Method, Url, InHeaders, InBody, Status, OutHeaders, OutBody]).
-
--export([status_is/2]).
-
--export([
- method/0, url/0, status/0, status_code/0, status_line/0, rheaders/0,
- has_rheader/1, rheader/1, rbody/0, header_is/3, body_is/2,
- body_has_string/2
-]).
-
-% ---
-% Tests
-
-%% @doc Assert that response status code is the given status code.
-status_is(Code, Desc) ->
- etap:is(status_code(), Code, Desc).
-
-header_is(Name, Value, Desc) ->
- etap:is(rheader(Name), Value, Desc).
-
-body_is(Value, Desc) ->
- etap:is(rbody(), Value, Desc).
-
-body_has_string(String, Desc) when is_list(OutBody), is_list(String) ->
- etap_string:contains_ok(OutBody, String, Desc).
-
-% ---
-% Accessor functions
-
-%% @doc Access a request's method.
-method() -> Method.
-
-%% @doc Access a request's URL.
-url() -> Url.
-
-%% @doc Access a request's status.
-status() -> Status.
-
-%% @doc Access a request's status code.
-status_code() ->
- {_, Code, _} = Status,
- Code.
-
-%% @doc Access a request's status line.
-status_line() ->
- {_, _, Line} = Status,
- Line.
-
-%% @doc Access a request's headers.
-rheaders() -> OutHeaders.
-
-%% @doc Dertermine if a specific request header exists.
-has_rheader(Key) ->
- lists:keymember(Key, 1, OutHeaders).
-
-%% @doc Return a specific request header.
-rheader(Key) ->
- case lists:keysearch(Key, 1, OutHeaders) of
- false -> undefined;
- {value, {Key, Value}} -> Value
- end.
-
-%% @doc Access the request's body.
-rbody() -> OutBody.
diff --git a/src/etap/etap_string.erl b/src/etap/etap_string.erl
deleted file mode 100644
index 67aa3d54..00000000
--- a/src/etap/etap_string.erl
+++ /dev/null
@@ -1,47 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @author Nick Gerakines <nick@gerakines.net> [http://socklabs.com/]
-%% @copyright 2008 Nick Gerakines
-%% @doc Provide testing functionality for strings.
--module(etap_string).
-
--export([contains_ok/3, is_before/4]).
-
-%% @spec contains_ok(string(), string(), string()) -> true | false
-%% @doc Assert that a string is contained in another string.
-contains_ok(Source, String, Desc) ->
- etap:isnt(
- string:str(Source, String),
- 0,
- Desc
- ).
-
-%% @spec is_before(string(), string(), string(), string()) -> true | false
-%% @doc Assert that a string comes before another string within a larger body.
-is_before(Source, StringA, StringB, Desc) ->
- etap:is_greater(
- string:str(Source, StringB),
- string:str(Source, StringA),
- Desc
- ).
diff --git a/src/etap/etap_web.erl b/src/etap/etap_web.erl
deleted file mode 100644
index fb7aee16..00000000
--- a/src/etap/etap_web.erl
+++ /dev/null
@@ -1,65 +0,0 @@
-%% Copyright (c) 2008-2009 Nick Gerakines <nick@gerakines.net>
-%%
-%% Permission is hereby granted, free of charge, to any person
-%% obtaining a copy of this software and associated documentation
-%% files (the "Software"), to deal in the Software without
-%% restriction, including without limitation the rights to use,
-%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-%% copies of the Software, and to permit persons to whom the
-%% Software is furnished to do so, subject to the following
-%% conditions:
-%%
-%% The above copyright notice and this permission notice shall be
-%% included in all copies or substantial portions of the Software.
-%%
-%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-%% OTHER DEALINGS IN THE SOFTWARE.
-%%
-%% @author Nick Gerakines <nick@gerakines.net> [http://socklabs.com/]
-%% @copyright 2008 Nick Gerakines
-%% @todo Support cookies.
-%% @doc Provide testing functionality for web requests.
--module(etap_web).
-
--export([simple_200/2, simple_404/2, build_request/4]).
-
-%% @doc Fetch a url and verify that it returned a 200 status.
-simple_200(Url, Desc) ->
- Request = build_request(get, Url, [], []),
- Request:status_is(200, Desc).
-
-%% @doc Fetch a url and verify that it returned a 404 status.
-simple_404(Url, Desc) ->
- Request = build_request(get, Url, [], []),
- Request:status_is(404, Desc).
-
-%% @doc Create and return a request structure.
-build_request(Method, Url, Headers, Body)
- when Method==options;Method==get;Method==head;Method==delete;Method==trace ->
- try http:request(Method, {Url, Headers}, [{autoredirect, false}], []) of
- {ok, {OutStatus, OutHeaders, OutBody}} ->
- etap_request:new(Method, Url, Headers, Body, OutStatus, OutHeaders, OutBody);
- _ -> error
- catch
- _:_ -> error
- end;
-
-%% @doc Create and return a request structure.
-build_request(Method, Url, Headers, Body) when Method == post; Method == put ->
- ContentType = case lists:keysearch("Content-Type", 1, Headers) of
- {value, {"Content-Type", X}} -> X;
- _ -> []
- end,
- try http:request(Method, {Url, Headers, ContentType, Body}, [{autoredirect, false}], []) of
- {ok, {OutStatus, OutHeaders, OutBody}} ->
- etap_request:new(Method, Url, Headers, Body, OutStatus, OutHeaders, OutBody);
- _ -> error
- catch
- _:_ -> error
- end.