Add test cases
diff --git a/src/constants.hrl b/src/constants.hrl
index 464702b..0f51aa6 100644
--- a/src/constants.hrl
+++ b/src/constants.hrl
@@ -1,8 +1,8 @@
 %% https://github.com/uber/jaeger-client-go/tree/v2.9.0/constants.go
 
 -define(JAEGER_CLIENT_VERSION_TAG_KEY, 'jaeger.version').
--define(JAEGER_DEBUG_HEADER, 'jaeger-debug-id').
--define(JAEGER_BAGGAGE_HEADER, 'jaeger-baggage').
+-define(JAEGER_DEBUG_HEADER, <<"jaeger-debug-id">>).
+-define(JAEGER_BAGGAGE_HEADER, <<"jaeger-baggage">>).
 -define(TRACER_HOSTNAME_TAG_KEY, 'hostname').
 -define(TRACER_IP_TAG_KEY, 'ip').
 -define(TRACER_STATE_HEADER_NAME, <<"uber-trace-id">>).
diff --git a/src/jaeger_passage_span_context.erl b/src/jaeger_passage_span_context.erl
index 0835f77..cbf01f9 100644
--- a/src/jaeger_passage_span_context.erl
+++ b/src/jaeger_passage_span_context.erl
@@ -112,15 +112,14 @@
         is_sampled = true
        };
 make_span_context_state([{_, Ref} | _]) ->
-    #?STATE{trace_id = TraceId} = passage_span_context:get_state(passage_span:get_context(Ref)),
+    #?STATE{trace_id = TraceId} =
+        passage_span_context:get_state(passage_span:get_context(Ref)),
     #?STATE{
         trace_id   = TraceId,
         span_id    = rand:uniform(16#FFFFFFFFFFFFFFFF),
         is_sampled = true
        }.
 
-%% https://github.com/jaegertracing/jaeger-client-go/blob/v2.9.0/propagation.go
-
 %% @private
 inject_span_context(Context, binary, InjectFun, Carrier) ->
     Bin0 = encode_state(passage_span_context:get_state(Context)),
@@ -136,7 +135,7 @@
             text_map ->
                 fun({K, V}) -> {?TRACE_BAGGAGE_HEADER(K), V} end;
             http_header ->
-                fun({K, V}) -> {?TRACE_BAGGAGE_HEADER(K), http_uri:encode(V)} end
+                fun({K, V}) -> {?TRACE_BAGGAGE_HEADER(K), escape(V)} end
         end,
     Items0 = lists:map(MapFun, maps:to_list(passage_span_context:get_baggage_items(Context))),
     Items1 = [{?TRACER_STATE_HEADER_NAME, state_to_string(State)} | Items0],
@@ -163,7 +162,7 @@
     DecodeValue =
         case Format of
             text_map -> fun (V) -> V end;
-            http_header -> fun http_uri:decode/1
+            http_header -> fun unescape/1
         end,
     Map = extract_to_map(IterateFun, Carrier, DecodeValue, #{}),
     case maps:is_key(state, Map) orelse maps:is_key(debug_id, Map) of
@@ -206,7 +205,8 @@
                                       Pairs0)],
                         maps:merge(Map0, maps:from_list(Pairs1));
                     ?TRACE_BAGGAGE_HEADER(Name) ->
-                        maps:put(Name, DecodeValue(V), Map0)
+                        maps:put(Name, DecodeValue(V), Map0);
+                    _ -> Map0
                 end,
             extract_to_map(IterateFun, Carrier1, DecodeValue, Map1)
     end.
@@ -278,3 +278,11 @@
 decode_baggage_items(<<KeySize:32, Key:KeySize/binary,
                        ValueSize:32, Value:ValueSize/binary, Bin/binary>>, Count, Items) ->
     decode_baggage_items(Bin, Count - 1, maps:put(Key, Value, Items)).
+
+-spec escape(binary()) -> binary().
+escape(Bin) ->
+    list_to_binary(http_uri:encode(binary_to_list(Bin))).
+
+-spec unescape(binary()) -> binary().
+unescape(Bin) ->
+    list_to_binary(http_uri:decode(binary_to_list(Bin))).
diff --git a/test/jaeger_passage_repoter_tests.erl b/test/jaeger_passage_repoter_tests.erl
new file mode 100644
index 0000000..38f8927
--- /dev/null
+++ b/test/jaeger_passage_repoter_tests.erl
@@ -0,0 +1,32 @@
+%% @copyright 2017 Takeru Ohta <phjgt308@gmail.com>
+-module(jaeger_passage_repoter_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+%%------------------------------------------------------------------------------
+%% Test Cases
+%%------------------------------------------------------------------------------
+basic_test() ->
+    {ok, _} = application:ensure_all_started(jaeger_passage),
+
+    %% Starts `test_reporter'
+    {ok, Reporter} = jaeger_passage_reporter:start(test_reporter),
+    [test_reporter] = jaeger_passage_reporter:which_reporters(),
+
+    %% Registers `test_tracer'
+    Context = jaeger_passage_span_context,
+    Sampler = passage_sampler_all:new(),
+    ok = passage_tracer_registry:register(test_tracer, Context, Sampler, Reporter),
+
+    %% Starts and finishes spans
+    passage_pd:start_root_span(test_root, test_tracer),
+    passage_pd:start_span(test_child),
+    passage_pd:error_log("Hello World"),
+    passage_pd:finish_span(),
+    passage_pd:finish_span(),
+    timer:sleep(50),
+
+    ok = jaeger_passage_reporter:stop(test_reporter),
+    [] = jaeger_passage_reporter:which_reporters(),
+
+    ok = application:stop(jaeger_passage).
diff --git a/test/jaeger_passage_span_context_tests.erl b/test/jaeger_passage_span_context_tests.erl
new file mode 100644
index 0000000..c792d50
--- /dev/null
+++ b/test/jaeger_passage_span_context_tests.erl
@@ -0,0 +1,109 @@
+%% @copyright 2017 Takeru Ohta <phjgt308@gmail.com>
+-module(jaeger_passage_span_context_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+
+%%------------------------------------------------------------------------------
+%% Test Cases
+%%------------------------------------------------------------------------------
+propagation_test_() ->
+    {foreach,
+     fun () -> {ok, _} = application:ensure_all_started(jaeger_passage) end,
+     fun (_) ->
+             ok = application:stop(jaeger_passage),
+             ok = application:stop(passage)
+     end,
+     [
+      {"Binary format",
+       fun () ->
+               ok = start_tracer(),
+               Span0 = passage:start_root_span(foo, tracer),
+               Span1 = passage:set_baggage_items(Span0, #{<<"a">> => <<"b">>}),
+
+               #{<<"binary">> := Injected} =
+                   passage:inject_span(Span1, binary, fun maps:put/3, #{}),
+
+               Extracted =
+                   passage:extract_span(
+                     tracer, binary,
+                     fun iterate_list/1, [{<<"binary">>, Injected}]),
+
+               ?assertEqual(
+                  passage_span:get_context(Span1),
+                  passage_span:get_context(Extracted))
+       end},
+      {"TextMap format",
+       fun () ->
+               ok = start_tracer(),
+               Span0 = passage:start_root_span(foo, tracer),
+               Span1 = passage:set_baggage_items(Span0, #{<<"a">> => <<"b">>}),
+
+               #{<<"uber-trace-id">> := _, <<"uberctx-a">> := _} = Injected =
+                   passage:inject_span(Span1, text_map, fun maps:put/3, #{}),
+
+               Extracted =
+                   passage:extract_span(
+                     tracer, text_map,
+                     fun iterate_list/1, maps:to_list(Injected)),
+
+               ?assertEqual(
+                  passage_span:get_context(Span1),
+                  passage_span:get_context(Extracted))
+       end},
+      {"HttpHeader format",
+       fun () ->
+               ok = start_tracer(),
+               Span0 = passage:start_root_span(foo, tracer),
+               Span1 = passage:set_baggage_items(Span0, #{<<"a">> => <<"b">>}),
+
+               #{<<"uber-trace-id">> := _, <<"uberctx-a">> := _} = Injected =
+                   passage:inject_span(Span1, http_header, fun maps:put/3, #{}),
+
+               Extracted =
+                   passage:extract_span(
+                     tracer, http_header,
+                     fun iterate_list/1, maps:to_list(Injected)),
+
+               ?assertEqual(
+                  passage_span:get_context(Span1),
+                  passage_span:get_context(Extracted))
+       end},
+      {"Debug ID",
+       fun () ->
+               ok = start_tracer(),
+               Span =
+                   passage:extract_span(
+                     tracer, text_map,
+                     fun iterate_list/1, [{<<"jaeger-debug-id">>, <<"foo">>}]),
+               Context = passage_span:get_context(Span),
+
+               ?assertEqual(0, jaeger_passage_span_context:get_span_id(Context)),
+               ?assertEqual({ok, <<"foo">>},
+                            jaeger_passage_span_context:get_debug_id(Context))
+       end},
+      {"Baggage Items",
+       fun () ->
+               ok = start_tracer(),
+               Span =
+                   passage:extract_span(
+                     tracer, text_map,
+                     fun iterate_list/1, [{<<"jaeger-debug-id">>, <<"foo">>},
+                                          {<<"jaeger-baggage">>, <<"a=b, 1=2">>}]),
+               ?assertEqual(#{<<"a">> => <<"b">>, <<"1">> => <<"2">>},
+                            passage:get_baggage_items(Span))
+       end}
+     ]}.
+
+%%------------------------------------------------------------------------------
+%% Internal Functions
+%%------------------------------------------------------------------------------
+-spec start_tracer() -> ok.
+start_tracer() ->
+    Context = jaeger_passage_span_context,
+    Sampler = passage_sampler_all:new(),
+    Reporter = passage_reporter_null:new(),
+    ok = passage_tracer_registry:register(tracer, Context, Sampler, Reporter).
+
+-spec iterate_list(list()) -> {ok, binary(), binary(), list()} | error.
+iterate_list([])              -> error;
+iterate_list([{K, V} | List]) -> {ok, K, V, List}.