From ca704a916ee05113564668cf5281700db25021f3 Mon Sep 17 00:00:00 2001 From: "Fabian N.C. van 't Hooft" Date: Wed, 7 Apr 2021 00:24:17 -0300 Subject: [PATCH] Add convenience function json2:obj_fetch/3 The json2:obj_fetch/2 either returns an object member's value or exits with a struct_no_key error if the object member is not found. Add json2:obj_fetch/3 that returns either the object member's value or a default value if the object member is not found. Add a new unit test for json2:obj_fetch/2,3 to the json2_SUITE. Also in json2_SUITE, fix the test source directories for the json2_decode_valid and json2_decode_invalid tests. Add asserts to verify that one or more test files are processed by those tests. --- src/json2.erl | 17 +++++++++++++++-- testsuite/json2_SUITE.erl | 25 ++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/json2.erl b/src/json2.erl index 64a8a4f94..b0cdb42a2 100644 --- a/src/json2.erl +++ b/src/json2.erl @@ -16,7 +16,7 @@ -module(json2). -export([encode/1, decode_string/1, decode/2]). --export([is_obj/1, obj_new/0, obj_fetch/2, obj_find/2, obj_is_key/2]). +-export([is_obj/1, obj_new/0, obj_fetch/2, obj_fetch/3, obj_find/2, obj_is_key/2]). -export([obj_store/3, obj_from_list/1, obj_fold/3]). -export([test/0]). -author("Jim Larson , Robert Wai-Chi Chu "). @@ -597,7 +597,7 @@ obj_new() -> {struct, []}. %% Fetch an object member's value, expecting it to be in the object. -%% Return value, runtime error if no member found with that name. +%% Return value, or runtime error if no member found with that name. obj_fetch(Key, {struct, Props}) when is_list(Props) -> case proplists:get_value(Key, Props) of @@ -607,6 +607,19 @@ obj_fetch(Key, {struct, Props}) when is_list(Props) -> Value end. + +%% Fetch an object member's value if the member exists. Return value +%% if found, or default if no member found with that name. + +obj_fetch(Key, {struct, Props}, Default) when is_list(Props) -> + case proplists:get_value(Key, Props) of + undefined -> + Default; + Value -> + Value + end. + + %% Fetch an object member's value, or indicate that there is no such member. %% Return {ok, Value} or 'error'. diff --git a/testsuite/json2_SUITE.erl b/testsuite/json2_SUITE.erl index 91db0c9ce..744d95b5f 100644 --- a/testsuite/json2_SUITE.erl +++ b/testsuite/json2_SUITE.erl @@ -8,7 +8,8 @@ all() -> [ json2_decode_valid, json2_decode_invalid, - json2_decode_invalid_utf8 + json2_decode_invalid_utf8, + json2_obj_fetch ]. groups() -> @@ -36,8 +37,9 @@ end_per_testcase(_Test, _Config) -> %%==================================================================== json2_decode_valid(_Config) -> - Dir = filename:join(?srcdir, "json2_SUITE_data/valid"), + Dir = filename:join(?data_srcdir(?MODULE), "valid"), Tests = filelib:wildcard(filename:join(Dir, "*.json")), + ?assertMatch([_|_], Tests), [begin {ok, Bin} = file:read_file(T), Str = unicode:characters_to_list(Bin), @@ -46,8 +48,9 @@ json2_decode_valid(_Config) -> ok. json2_decode_invalid(_Config) -> - Dir = filename:join(?srcdir, "json2_SUITE_data/invalid"), + Dir = filename:join(?data_srcdir(?MODULE), "invalid"), Tests = filelib:wildcard(filename:join(Dir, "*.json")), + ?assertMatch([_|_], Tests), [begin {ok, Bin} = file:read_file(T), Str = unicode:characters_to_list(Bin), @@ -61,3 +64,19 @@ json2_decode_invalid_utf8(_Config) -> ?assertMatch({Str1, {error, _}}, {Str1, json2:decode_string(Str1)}), ?assertMatch({Str2, {error, _}}, {Str2, json2:decode_string(Str2)}), ok. + +json2_obj_fetch(_Config) -> + F = filename:join(?data_srcdir(?MODULE), "valid/simple-object.json"), + {ok, Bin} = file:read_file(F), + Str = unicode:characters_to_list(Bin), + {ok, Obj} = json2:decode_string(Str), + ?assertEqual({array,[]}, json2:obj_fetch("a", Obj)), + NotFound = try + json2:obj_fetch("b", Obj) + catch + C:Exc -> + {C, Exc} + end, + ?assertEqual({exit, {struct_no_key, "b"}}, NotFound), + ?assertEqual(foo, json2:obj_fetch("b", Obj, foo)), + ok.