Skip to content

Commit

Permalink
Merge pull request #2 from inaka/jfacorro.1.katana.maps
Browse files Browse the repository at this point in the history
[#1] get/[2,3] nested maps.
  • Loading branch information
Federico Carrone committed Aug 12, 2014
2 parents e1fdf03 + aa3a64d commit 5eba242
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ logs
bin
ebin
deps
.erlang.mk.*
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
PROJECT = katana

DEPS = sync

dep_sync = git https://github.com/rustyio/sync.git master

include erlang.mk

CT_SUITES = ktn_maps

shell: app
erl -pa ebin -pa deps/*/ebin -s sync
39 changes: 39 additions & 0 deletions src/ktn_maps.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-module(ktn_maps).

-export([
get/2,
get/3
]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Public API
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec get(term(), map()) -> term().
get(Keys, Map) ->
get(Keys, Map, undefined, error).

-spec get(term(), map(), term()) -> term().
get(Keys, Map, Default) ->
get(Keys, Map, Default, default).

%% @private
-spec get(term(), map(), term(), error | default) -> term().
get([Key], Map, Default, Type) ->
get(Key, Map, Default, Type);
get([Key | Rest], Map, Default, Type) ->
case get(Key, Map, Default, Type) of
NewMap when is_map(NewMap) ->
get(Rest, NewMap, Default, Type);
_ ->
Default
end;
get(Key, Map, Default, Type) ->
case {Type, maps:is_key(Key, Map)} of
{_, true} ->
maps:get(Key, Map);
{default, false} ->
Default;
{error, false} ->
error(bad_path)
end.
121 changes: 121 additions & 0 deletions test/ktn_maps_SUITE.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
-module(ktn_maps_SUITE).

-export([
all/0,
init_per_suite/1,
end_per_suite/1
]).

-export([
find_nested_values/1,
find_shallow_values/1,
dont_find_nested_values/1,
dont_find_shallow_values/1,
provide_default/1
]).

-define(EXCLUDED_FUNS,
[
module_info,
all,
test,
init_per_suite,
end_per_suite
]).

-type config() :: [{atom(), term()}].

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Common test
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec all() -> [atom()].
all() ->
Exports = ?MODULE:module_info(exports),
[F || {F, _} <- Exports, not lists:member(F, ?EXCLUDED_FUNS)].

-spec init_per_suite(config()) -> config().
init_per_suite(Config) ->
Map = #{user => "john.doe",
name => "John",
last_name => "Doe",
location => #{latitude => 1.5,
longitude => 2.5},
conversation => #{destination => #{ip => "127.0.0.1",
port => 8080}}
},
[{map, Map} | Config].

-spec end_per_suite(config()) -> config().
end_per_suite(Config) ->
Config.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Test Cases
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

-spec find_nested_values(config()) -> ok.
find_nested_values(Config) ->
Map = proplists:get_value(map, Config),
8080 = ktn_maps:get([conversation, destination, port], Map),
1.5 = ktn_maps:get([location, latitude], Map).

-spec find_shallow_values(config()) -> ok.
find_shallow_values(Config) ->
Map = proplists:get_value(map, Config),
"john.doe" = ktn_maps:get(user, Map),
"John" = ktn_maps:get(name, Map),
"Doe" = ktn_maps:get(last_name, Map),
"john.doe" = ktn_maps:get([user], Map).

-spec dont_find_nested_values(config()) -> ok.
dont_find_nested_values(Config) ->
Map = proplists:get_value(map, Config),
ok = try
ktn_maps:get([address, country, city], Map)
catch
error:bad_path -> ok
end,
ok = try
ktn_maps:get([social, facebook], Map)
catch
error:bad_path -> ok
end.

-spec dont_find_shallow_values(config()) -> ok.
dont_find_shallow_values(Config) ->
Map = proplists:get_value(map, Config),
ok = try
ktn_maps:get(username, Map)
catch
error:bad_path -> ok
end,
ok = try
ktn_maps:get(email, Map)
catch
error:bad_path -> ok
end,
ok = try
ktn_maps:get([email], Map)
catch
error:bad_path -> ok
end.

-spec provide_default(config()) -> ok.
provide_default(Config) ->
Map = proplists:get_value(map, Config),

8080 = ktn_maps:get([conversation, destination, port], Map, default),
1.5 = ktn_maps:get([location, latitude], Map, default),

"john.doe" = ktn_maps:get(user, Map, default),
"John" = ktn_maps:get(name, Map, default),
"Doe" = ktn_maps:get(last_name, Map, default),
"john.doe" = ktn_maps:get([user], Map, default),

default = ktn_maps:get([address, country, city], Map, default),
default = ktn_maps:get([social, facebook], Map, default),

default = ktn_maps:get(username, Map, default),
default = ktn_maps:get(email, Map, default),
default = ktn_maps:get([email], Map, default).

0 comments on commit 5eba242

Please sign in to comment.