Skip to content

Instantly share code, notes, and snippets.

@maxlapshin
Created September 21, 2020 22:10
Show Gist options
  • Save maxlapshin/dad9927a6dbb9a6e14417aed7d31e567 to your computer and use it in GitHub Desktop.
Save maxlapshin/dad9927a6dbb9a6e14417aed7d31e567 to your computer and use it in GitHub Desktop.
-module(type_mapper_SUITE).
-compile(nowarn_export_all).
-compile(nowarn_unused_record).
-compile(nowarn_unused_type).
-compile(export_all).
-compile({parse_transform,type_mapper}).
all() ->
[{group, from_json}].
groups() ->
[{from_json, [], [
non_neg_integer,
non_neg_integer_with_undefined,
integer_with_default,
binary,
outer_rec,
atom_value,
boolean,
wrapped_type,
user_union,
map_type
]}].
-record(non_neg_integer, {
key :: non_neg_integer()
}).
-type t_non_neg_int() :: #non_neg_integer{}.
non_neg_integer(_) ->
{ok, #non_neg_integer{key = 15}} = type_mapper:json2rec(?MODULE, t_non_neg_int, #{<<"key">> => 15}),
{ok, #non_neg_integer{key = 15}} = type_mapper:json2rec(?MODULE, t_non_neg_int, #{key => 15}),
{error, #{path := [key], reason := lacks_mandatory}} = type_mapper:json2rec(?MODULE, t_non_neg_int, #{}),
{error, #{path := [key], reason := negative_integer}} = type_mapper:json2rec(?MODULE, t_non_neg_int, #{key => -15}),
{error, #{path := [key], reason := non_integer}} = type_mapper:json2rec(?MODULE, t_non_neg_int, #{key => <<"15">>}),
ok.
-record(non_neg_integer_with_undefined, {
key :: non_neg_integer() | undefined
}).
-type non_neg_integer_with_undefined() :: #non_neg_integer_with_undefined{}.
non_neg_integer_with_undefined(_) ->
{ok, #non_neg_integer_with_undefined{key = 15}} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{<<"key">> => 15}),
{ok, #non_neg_integer_with_undefined{key = 15}} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{key => 15}),
{ok, #non_neg_integer_with_undefined{key = undefined}} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{key => undefined}),
{ok, #non_neg_integer_with_undefined{key = undefined}} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{key => null}),
% Вопрос: если у нас допустим undefined среди типов, то считаем ли мы его
% дефолтным значением, которое можно не указывать? Пока что решаем, что нет, нельзя
% #non_neg_integer_with_undefined{key = undefined} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{}),
{error, #{path := [key], reason := lacks_mandatory}} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{}),
{error, #{path := [key], reason := negative_integer}} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{key => -15}),
{error, #{path := [key], reason := non_integer}} = type_mapper:json2rec(?MODULE, non_neg_integer_with_undefined, #{key => <<"15">>}),
ok.
-record(integer_with_default, {
key = 5 :: integer()
}).
-type integer_with_default() :: #integer_with_default{}.
integer_with_default(_) ->
{ok, #integer_with_default{key = 15}} = type_mapper:json2rec(?MODULE, integer_with_default, #{<<"key">> => 15}),
{ok, #integer_with_default{key = -15}} = type_mapper:json2rec(?MODULE, integer_with_default, #{key => -15}),
{ok, #integer_with_default{key = 5}} = type_mapper:json2rec(?MODULE, integer_with_default, #{}),
{error, #{path := [key], reason := non_integer}} = type_mapper:json2rec(?MODULE, integer_with_default, #{key => <<"15">>}),
ok.
-record(nested_rec, {
key :: integer()
}).
-type nested_rec() :: #nested_rec{}.
-record(outer_rec, {
nested :: nested_rec()
}).
-type outer_rec() :: #outer_rec{}.
outer_rec(_) ->
{ok, #outer_rec{nested = #nested_rec{key = 10}}} = type_mapper:json2rec(?MODULE, outer_rec, #{nested => #{key => 10}}),
{ok, #outer_rec{nested = #nested_rec{key = 10}}} = type_mapper:json2rec(?MODULE, outer_rec, #{<<"nested">> => #{key => 10}}),
{ok, #outer_rec{nested = #nested_rec{key = 10}}} = type_mapper:json2rec(?MODULE, outer_rec, #{<<"nested">> => #{<<"key">> => 10}}),
ok.
-record(atom_value, {
key :: a | b | c | non_neg_integer()
}).
-type atom_value() :: #atom_value{}.
atom_value(_) ->
{ok, #atom_value{key = a}} = type_mapper:json2rec(?MODULE, atom_value, #{key => <<"a">>}),
{ok, #atom_value{key = 5}} = type_mapper:json2rec(?MODULE, atom_value, #{key => 5}),
ok.
-record(boolean, {
key :: boolean()
}).
-type t_boolean() :: #boolean{}.
boolean(_) ->
{ok, #boolean{key = true}} = type_mapper:json2rec(?MODULE, t_boolean, #{key => <<"true">>}),
{ok, #boolean{key = true}} = type_mapper:json2rec(?MODULE, t_boolean, #{key => true}),
{ok, #boolean{key = false}} = type_mapper:json2rec(?MODULE, t_boolean, #{key => <<"false">>}),
{ok, #boolean{key = false}} = type_mapper:json2rec(?MODULE, t_boolean, #{key => false}),
ok.
-type deprecated_boolean() :: boolean().
-record(wrapped_type, {
key :: deprecated_boolean()
}).
-type wrapped_type() :: #wrapped_type{}.
wrapped_type(_) ->
{ok, #wrapped_type{key = true}} = type_mapper:json2rec(?MODULE, wrapped_type, #{key => true}),
ok.
-type user_union() :: a|b|c.
-record(user_unioned, {
key :: user_union()
}).
-type user_unioned() :: #user_unioned{}.
user_union(_) ->
{ok, #user_unioned{key = a}} = type_mapper:json2rec(?MODULE, user_unioned, #{<<"key">> => <<"a">>}),
ok.
-record(item, {
title :: binary()
}).
-type item() :: #item{}.
-record(container, {
items = #{} :: #{binary() => item()}
}).
-type container() :: #container{}.
map_type(_) ->
{ok, #container{items = #{<<"a">> := #item{title = <<"b">>} }}} =
type_mapper:json2rec(?MODULE, container, #{<<"items">> => #{<<"a">> => #{<<"title">> => <<"b">>}}}),
ok.
-record(binary_rec, {
key :: binary()
}).
-type binary_rec() :: #binary_rec{}.
binary(_) ->
{ok, #binary_rec{key = <<"value">>}} = type_mapper:json2rec(?MODULE, binary_rec, #{key => <<"value">>}),
{ok, #binary_rec{key = <<"value">>}} = type_mapper:json2rec(?MODULE, binary_rec, #{key => value}),
ok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment