diff --git a/modules/openapi-generator/src/main/resources/erlang-proper/api.mustache b/modules/openapi-generator/src/main/resources/erlang-proper/api.mustache index 7861cfbeb32..30d2b92d236 100644 --- a/modules/openapi-generator/src/main/resources/erlang-proper/api.mustache +++ b/modules/openapi-generator/src/main/resources/erlang-proper/api.mustache @@ -18,13 +18,20 @@ Method = {{httpMethod}}, Host = application:get_env({{packageName}}, host, "http://localhost:8080"), Path = ["{{{replacedPathName}}}"], + {{#isBodyAllowed}} Body = {{^formParams.isEmpty}}{form, [{{#formParams}}{{#required}}{{^-first}}, {{/-first}}{<<"{{{baseName}}}">>, {{paramName}}{{/required}}{{/formParams}}]++{{packageName}}_utils:optional_params([{{#formParams}}{{^required}}{{^-first}}, {{/-first}}'{{{baseName}}}'{{/required}}{{/formParams}}], _OptionalParams)}{{/formParams.isEmpty}}{{#formParams.isEmpty}}{{#bodyParams.isEmpty}}[]{{/bodyParams.isEmpty}}{{^bodyParams.isEmpty}}{{#bodyParams}}{{paramName}}{{/bodyParams}}{{/bodyParams.isEmpty}}{{/formParams.isEmpty}}, - ContentType = {{#hasConsumes}}hd([{{#consumes}}{{^-first}}, {{/-first}}"{{mediaType}}"{{/consumes}}]){{/hasConsumes}}{{^hasConsumes}}<<"text/plain">>{{/hasConsumes}}, + ContentType = {{#hasConsumes}}hd([{{#consumes}}{{^-first}}, {{/-first}}"{{mediaType}}"{{/consumes}}]){{/hasConsumes}}{{^hasConsumes}}"text/plain"{{/hasConsumes}}, + {{/isBodyAllowed}} {{^queryParams.isEmpty}} QueryString = [{{#queryParams}}{{^-first}}, {{/-first}}<<"{{{baseName}}}=">>, {{{paramName}}}, <<"&">>{{/queryParams}}], {{/queryParams.isEmpty}} + {{#isBodyAllowed}} {{packageName}}_utils:request(Method, [Host, ?BASE_URL, Path{{^queryParams.isEmpty}}, <<"?">>, QueryString{{/queryParams.isEmpty}}], jsx:encode(Body), ContentType). + {{/isBodyAllowed}} + {{^isBodyAllowed}} + {{packageName}}_utils:request(Method, [Host, ?BASE_URL, Path{{^queryParams.isEmpty}}, <<"?">>, QueryString{{/queryParams.isEmpty}}]). + {{/isBodyAllowed}} {{/operation}} {{/operations}} diff --git a/modules/openapi-generator/src/main/resources/erlang-proper/model.mustache b/modules/openapi-generator/src/main/resources/erlang-proper/model.mustache index 5e4024ed8d3..9ec89287ba8 100644 --- a/modules/openapi-generator/src/main/resources/erlang-proper/model.mustache +++ b/modules/openapi-generator/src/main/resources/erlang-proper/model.mustache @@ -5,7 +5,9 @@ -include("{{packageName}}.hrl"). -export([{{classname}}/0]). - +{{^isEnum}}{{^isArrayModel}} +-export([{{classname}}/1]). +{{/isArrayModel}}{{/isEnum}} -export_type([{{classname}}/0]). -type {{classname}}() ::{{#isEnum}} @@ -15,12 +17,23 @@ | {{/-first}}{'{{name}}', {{dataType}} }{{/vars}} ].{{/isArrayModel}}{{/isEnum}} -{{classname}}() ->{{#isEnum}} +{{#isEnum}} +{{classname}}() -> elements([{{#allowableValues.values}}{{^-first}}, {{/-first}}<<"{{.}}">>{{/allowableValues.values}}]). - {{/isEnum}}{{#isArrayModel}} - list({{arrayModelType}}{{#minItems}}, {{minItems}}{{#maxItems}}, {{maxItems}}{{/maxItems}}{{/minItems}}).{{/isArrayModel}}{{^isEnum}}{{^isArrayModel}} - [ {{#vars}}{{^-first}} - , {{/-first}}{'{{baseName}}', {{#isString}}{{#isEnum}}elements([{{#allowableValues.values}}{{^-first}}, {{/-first}}<<"{{.}}">>{{/allowableValues.values}}]){{/isEnum}}{{^isEnum}}binary({{#minLength}}{{minLength}}{{#maxLength}}, {{maxLength}}{{/maxLength}}{{/minLength}}){{/isEnum}}{{/isString}}{{^isString}}{{baseType}}{{/isString}} }{{/vars}} - ].{{/isArrayModel}}{{/isEnum}} +{{/isEnum}} +{{#isArrayModel}} +{{classname}}() -> + list({{arrayModelType}}{{#minItems}}, {{minItems}}{{#maxItems}}, {{maxItems}}{{/maxItems}}{{/minItems}}). +{{/isArrayModel}} +{{^isEnum}}{{^isArrayModel}} +{{classname}}() -> + {{classname}}([]). + +{{classname}}(Fields) -> + Default = [ {{#vars}}{{^-first}} + , {{/-first}}{'{{baseName}}', {{#isString}}{{#isEnum}}elements([{{#allowableValues.values}}{{^-first}}, {{/-first}}<<"{{.}}">>{{/allowableValues.values}}]){{/isEnum}}{{^isEnum}}binary({{#minLength}}{{minLength}}{{#maxLength}}, {{maxLength}}{{/maxLength}}{{/minLength}}){{/isEnum}}{{/isString}}{{^isString}}{{baseType}}{{/isString}} }{{/vars}} + ], + lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)). +{{/isArrayModel}}{{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/main/resources/erlang-proper/rebar.config.mustache b/modules/openapi-generator/src/main/resources/erlang-proper/rebar.config.mustache index 4a1593adca4..0545ca808a5 100644 --- a/modules/openapi-generator/src/main/resources/erlang-proper/rebar.config.mustache +++ b/modules/openapi-generator/src/main/resources/erlang-proper/rebar.config.mustache @@ -4,4 +4,4 @@ {shell, [{apps, [{{packageName}}]}]}. -{plugins, [rebar3_proper]}. +{plugins, [rebar3_proper]}. \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/erlang-proper/statem.hrl.mustache b/modules/openapi-generator/src/main/resources/erlang-proper/statem.hrl.mustache index 7b4dd931aa3..ab137181671 100644 --- a/modules/openapi-generator/src/main/resources/erlang-proper/statem.hrl.mustache +++ b/modules/openapi-generator/src/main/resources/erlang-proper/statem.hrl.mustache @@ -1,25 +1,49 @@ %%============================================================================== -%% Setup +%% Syntactic sugar %%============================================================================== -setup() -> ok. +command(State) -> + Funs0 = [ {F, list_to_atom(atom_to_list(F) ++ "_args")} + || {F, _} <- ?MODULE:module_info(exports) + ], -%%============================================================================== -%% Cleanup -%%============================================================================== + Funs1 = [ X || {_, FArgs} = X <- Funs0, + erlang:function_exported(?MODULE, FArgs, 1) + ], -cleanup() -> ok. + WeightFun = case erlang:function_exported(?MODULE, weight, 1) of + true -> fun ?MODULE:weight/1; + false -> fun(_) -> 1 end + end, -%%============================================================================== -%% Initial State -%%============================================================================== + proper_types:frequency([ { WeightFun(F) + , {call, ?MODULE, F, ?MODULE:FArgs(State)} + } + || {F, FArgs} <- Funs1 + ]). -initial_state() -> #{}. +precondition(S, {call, M, F, Args}) -> + Pre = list_to_atom(atom_to_list(F) ++ "_pre"), + case erlang:function_exported(M, Pre, 1) of + true -> M:Pre(S); + false -> true + end + andalso + case erlang:function_exported(M, Pre, 2) of + true -> M:Pre(S, Args); + false -> true + end. -%%============================================================================== -%% State transitions callbacks -%% -%% operation_pre(State) -> true. -%% operation_next(State, Result, Args) -> State. -%% operation_post(State, Args, Result) -> true. -%%============================================================================== +next_state(S, Res, {call, M, F, Args}) -> + Next = list_to_atom(atom_to_list(F) ++ "_next"), + case erlang:function_exported(M, Next, 3) of + true -> M:Next(S, Res, Args); + false -> S + end. + +postcondition(S, {call, M, F, Args}, Res) -> + Post = list_to_atom(atom_to_list(F) ++ "_post"), + case erlang:function_exported(M, Post, 3) of + true -> M:Post(S, Args, Res); + false -> true + end. diff --git a/modules/openapi-generator/src/main/resources/erlang-proper/statem.mustache b/modules/openapi-generator/src/main/resources/erlang-proper/statem.mustache index 98ebdf1c54c..81af4eafa7a 100644 --- a/modules/openapi-generator/src/main/resources/erlang-proper/statem.mustache +++ b/modules/openapi-generator/src/main/resources/erlang-proper/statem.mustache @@ -9,66 +9,7 @@ -compile(export_all). -compile(nowarn_export_all). -%%============================================================================== -%% PropEr callbacks -%%============================================================================== - -command(State) -> - Funs0 = [ {F, list_to_atom(atom_to_list(F) ++ "_args")} - || {F, _} <- ?MODULE:module_info(exports) - ], - - Funs1 = [ X || {_, FArgs} = X <- Funs0, - erlang:function_exported(?MODULE, FArgs, 1) - ], - proper_types:oneof([ {call, ?MODULE, F, ?MODULE:FArgs(State)} - || {F, FArgs} <- Funs1 - ]). - -precondition(S, {call, M, F, Args}) -> - Pre = list_to_atom(atom_to_list(F) ++ "_pre"), - case erlang:function_exported(M, Pre, 1) of - true -> M:Pre(S); - false -> true - end - andalso - case erlang:function_exported(M, Pre, 2) of - true -> M:Pre(S, Args); - false -> true - end. - -next_state(S, Res, {call, M, F, Args}) -> - Next = list_to_atom(atom_to_list(F) ++ "_next"), - case erlang:function_exported(M, Next, 3) of - true -> M:Next(S, Res, Args); - false -> S - end. - -postcondition(S, {call, M, F, Args}, Res) -> - Post = list_to_atom(atom_to_list(F) ++ "_post"), - case erlang:function_exported(M, Post, 3) of - true -> M:Post(S, Args, Res); - false -> true - end. - -{{#operations}} -{{#operation}} -%%============================================================================== -%% {{operationId}} -%%============================================================================== - -{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}) -> - {{classname}}_api:{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}). - -{{operationId}}_args(S) -> - Args = [{{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{dataType}}{{/required}}{{/allParams}}], - case erlang:function_exported(?MODULE, '{{operationId}}_args_custom', 2) of - true -> ?MODULE:{{operationId}}_args_custom(S, Args); - false -> Args - end. - -{{/operation}} -{{/operations}} +-include("{{packageName}}_statem.hrl"). %%============================================================================== %% The statem's property @@ -99,7 +40,34 @@ prop_main() -> ). %%============================================================================== -%% Include file with setup, cleanup, initial_state -%% and state transitions callbacks +%% Setup %%============================================================================== --include("{{classname}}_statem.hrl"). + +setup() -> ok. + +%%============================================================================== +%% Cleanup +%%============================================================================== + +cleanup() -> ok. + +%%============================================================================== +%% Initial State +%%============================================================================== + +initial_state() -> #{}. + +{{#operations}} +{{#operation}} +%%============================================================================== +%% {{operationId}} +%%============================================================================== + +{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}) -> + {{classname}}_api:{{operationId}}({{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{paramName}}{{/required}}{{/allParams}}). + +{{operationId}}_args(_S) -> + [{{#allParams}}{{#required}}{{^-first}}, {{/-first}}{{dataType}}{{/required}}{{/allParams}}]. + +{{/operation}} +{{/operations}} \ No newline at end of file diff --git a/samples/client/petstore/erlang-proper/.gitignore b/samples/client/petstore/erlang-proper/.gitignore new file mode 100644 index 00000000000..172c6579a4a --- /dev/null +++ b/samples/client/petstore/erlang-proper/.gitignore @@ -0,0 +1,2 @@ +_build/ +rebar.lock diff --git a/samples/client/petstore/erlang-proper/.openapi-generator/VERSION b/samples/client/petstore/erlang-proper/.openapi-generator/VERSION index 6d94c9c2e12..a6527129083 100644 --- a/samples/client/petstore/erlang-proper/.openapi-generator/VERSION +++ b/samples/client/petstore/erlang-proper/.openapi-generator/VERSION @@ -1 +1 @@ -3.3.0-SNAPSHOT \ No newline at end of file +3.3.2-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/erlang-proper/rebar.config b/samples/client/petstore/erlang-proper/rebar.config index 0060c9afec5..5aaea33d28b 100644 --- a/samples/client/petstore/erlang-proper/rebar.config +++ b/samples/client/petstore/erlang-proper/rebar.config @@ -4,4 +4,4 @@ {shell, [{apps, [petstore]}]}. -{plugins, [rebar3_proper]}. +{plugins, [rebar3_proper]}. \ No newline at end of file diff --git a/samples/client/petstore/erlang-proper/src/model/petstore_api_response.erl b/samples/client/petstore/erlang-proper/src/model/petstore_api_response.erl index 495861559a8..ede40657502 100644 --- a/samples/client/petstore/erlang-proper/src/model/petstore_api_response.erl +++ b/samples/client/petstore/erlang-proper/src/model/petstore_api_response.erl @@ -4,6 +4,8 @@ -export([petstore_api_response/0]). +-export([petstore_api_response/1]). + -export_type([petstore_api_response/0]). -type petstore_api_response() :: @@ -12,8 +14,14 @@ | {'message', binary() } ]. + petstore_api_response() -> - [ {'code', integer() } - , {'type', binary() } - , {'message', binary() } - ]. + petstore_api_response([]). + +petstore_api_response(Fields) -> + Default = [ {'code', integer() } + , {'type', binary() } + , {'message', binary() } + ], + lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)). + diff --git a/samples/client/petstore/erlang-proper/src/model/petstore_category.erl b/samples/client/petstore/erlang-proper/src/model/petstore_category.erl index d048667c354..28a0292cfaf 100644 --- a/samples/client/petstore/erlang-proper/src/model/petstore_category.erl +++ b/samples/client/petstore/erlang-proper/src/model/petstore_category.erl @@ -4,6 +4,8 @@ -export([petstore_category/0]). +-export([petstore_category/1]). + -export_type([petstore_category/0]). -type petstore_category() :: @@ -11,7 +13,13 @@ | {'name', binary() } ]. + petstore_category() -> - [ {'id', integer() } - , {'name', binary() } - ]. + petstore_category([]). + +petstore_category(Fields) -> + Default = [ {'id', integer() } + , {'name', binary() } + ], + lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)). + diff --git a/samples/client/petstore/erlang-proper/src/model/petstore_order.erl b/samples/client/petstore/erlang-proper/src/model/petstore_order.erl index 360e5cf4287..c66d2bdd2b2 100644 --- a/samples/client/petstore/erlang-proper/src/model/petstore_order.erl +++ b/samples/client/petstore/erlang-proper/src/model/petstore_order.erl @@ -4,6 +4,8 @@ -export([petstore_order/0]). +-export([petstore_order/1]). + -export_type([petstore_order/0]). -type petstore_order() :: @@ -15,11 +17,17 @@ | {'complete', boolean() } ]. + petstore_order() -> - [ {'id', integer() } - , {'petId', integer() } - , {'quantity', integer() } - , {'shipDate', datetime() } - , {'status', elements([<<"placed">>, <<"approved">>, <<"delivered">>]) } - , {'complete', boolean() } - ]. + petstore_order([]). + +petstore_order(Fields) -> + Default = [ {'id', integer() } + , {'petId', integer() } + , {'quantity', integer() } + , {'shipDate', datetime() } + , {'status', elements([<<"placed">>, <<"approved">>, <<"delivered">>]) } + , {'complete', boolean() } + ], + lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)). + diff --git a/samples/client/petstore/erlang-proper/src/model/petstore_pet.erl b/samples/client/petstore/erlang-proper/src/model/petstore_pet.erl index 77bbd704fef..492f70d63a4 100644 --- a/samples/client/petstore/erlang-proper/src/model/petstore_pet.erl +++ b/samples/client/petstore/erlang-proper/src/model/petstore_pet.erl @@ -4,6 +4,8 @@ -export([petstore_pet/0]). +-export([petstore_pet/1]). + -export_type([petstore_pet/0]). -type petstore_pet() :: @@ -15,11 +17,17 @@ | {'status', binary() } ]. + petstore_pet() -> - [ {'id', integer() } - , {'category', petstore_category:petstore_category() } - , {'name', binary() } - , {'photoUrls', list(binary()) } - , {'tags', list(petstore_tag:petstore_tag()) } - , {'status', elements([<<"available">>, <<"pending">>, <<"sold">>]) } - ]. + petstore_pet([]). + +petstore_pet(Fields) -> + Default = [ {'id', integer() } + , {'category', petstore_category:petstore_category() } + , {'name', binary() } + , {'photoUrls', list(binary()) } + , {'tags', list(petstore_tag:petstore_tag()) } + , {'status', elements([<<"available">>, <<"pending">>, <<"sold">>]) } + ], + lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)). + diff --git a/samples/client/petstore/erlang-proper/src/model/petstore_tag.erl b/samples/client/petstore/erlang-proper/src/model/petstore_tag.erl index 31bfe4fadb1..56b5e5f55bc 100644 --- a/samples/client/petstore/erlang-proper/src/model/petstore_tag.erl +++ b/samples/client/petstore/erlang-proper/src/model/petstore_tag.erl @@ -4,6 +4,8 @@ -export([petstore_tag/0]). +-export([petstore_tag/1]). + -export_type([petstore_tag/0]). -type petstore_tag() :: @@ -11,7 +13,13 @@ | {'name', binary() } ]. + petstore_tag() -> - [ {'id', integer() } - , {'name', binary() } - ]. + petstore_tag([]). + +petstore_tag(Fields) -> + Default = [ {'id', integer() } + , {'name', binary() } + ], + lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)). + diff --git a/samples/client/petstore/erlang-proper/src/model/petstore_user.erl b/samples/client/petstore/erlang-proper/src/model/petstore_user.erl index df35576aa43..6e97ea6b836 100644 --- a/samples/client/petstore/erlang-proper/src/model/petstore_user.erl +++ b/samples/client/petstore/erlang-proper/src/model/petstore_user.erl @@ -4,6 +4,8 @@ -export([petstore_user/0]). +-export([petstore_user/1]). + -export_type([petstore_user/0]). -type petstore_user() :: @@ -17,13 +19,19 @@ | {'userStatus', integer() } ]. + petstore_user() -> - [ {'id', integer() } - , {'username', binary() } - , {'firstName', binary() } - , {'lastName', binary() } - , {'email', binary() } - , {'password', binary() } - , {'phone', binary() } - , {'userStatus', integer() } - ]. + petstore_user([]). + +petstore_user(Fields) -> + Default = [ {'id', integer() } + , {'username', binary() } + , {'firstName', binary() } + , {'lastName', binary() } + , {'email', binary() } + , {'password', binary() } + , {'phone', binary() } + , {'userStatus', integer() } + ], + lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)). + diff --git a/samples/client/petstore/erlang-proper/src/petstore_api.erl b/samples/client/petstore/erlang-proper/src/petstore_api.erl index fe3fe661b3f..2f852cfd407 100644 --- a/samples/client/petstore/erlang-proper/src/petstore_api.erl +++ b/samples/client/petstore/erlang-proper/src/petstore_api.erl @@ -21,7 +21,7 @@ create_user(PetstoreUser) -> Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user"], Body = PetstoreUser, - ContentType = <<"text/plain">>, + ContentType = "text/plain", petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType). @@ -34,7 +34,7 @@ create_users_with_array_input(PetstoreUserArray) -> Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user/createWithArray"], Body = PetstoreUserArray, - ContentType = <<"text/plain">>, + ContentType = "text/plain", petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType). @@ -47,7 +47,7 @@ create_users_with_list_input(PetstoreUserArray) -> Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user/createWithList"], Body = PetstoreUserArray, - ContentType = <<"text/plain">>, + ContentType = "text/plain", petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType). @@ -59,10 +59,8 @@ delete_user(Username) -> Method = delete, Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user/", Username, ""], - Body = [], - ContentType = <<"text/plain">>, - petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType). + petstore_utils:request(Method, [Host, ?BASE_URL, Path]). %% @doc Get user by user name %% @@ -72,10 +70,8 @@ get_user_by_name(Username) -> Method = get, Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user/", Username, ""], - Body = [], - ContentType = <<"text/plain">>, - petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType). + petstore_utils:request(Method, [Host, ?BASE_URL, Path]). %% @doc Logs user into the system %% @@ -85,11 +81,9 @@ login_user(Username, Password) -> Method = get, Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user/login"], - Body = [], - ContentType = <<"text/plain">>, QueryString = [<<"username=">>, Username, <<"&">>, <<"password=">>, Password, <<"&">>], - petstore_utils:request(Method, [Host, ?BASE_URL, Path, <<"?">>, QueryString], jsx:encode(Body), ContentType). + petstore_utils:request(Method, [Host, ?BASE_URL, Path, <<"?">>, QueryString]). %% @doc Logs out current logged in user session %% @@ -99,10 +93,8 @@ logout_user() -> Method = get, Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user/logout"], - Body = [], - ContentType = <<"text/plain">>, - petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType). + petstore_utils:request(Method, [Host, ?BASE_URL, Path]). %% @doc Updated user %% This can only be done by the logged in user. @@ -113,7 +105,7 @@ update_user(Username, PetstoreUser) -> Host = application:get_env(petstore, host, "http://localhost:8080"), Path = ["/user/", Username, ""], Body = PetstoreUser, - ContentType = <<"text/plain">>, + ContentType = "text/plain", petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType). diff --git a/samples/client/petstore/erlang-proper/src/petstore_statem.erl b/samples/client/petstore/erlang-proper/src/petstore_statem.erl index d7e769cdaee..9244c6fbf0c 100644 --- a/samples/client/petstore/erlang-proper/src/petstore_statem.erl +++ b/samples/client/petstore/erlang-proper/src/petstore_statem.erl @@ -9,160 +9,7 @@ -compile(export_all). -compile(nowarn_export_all). -%%============================================================================== -%% PropEr callbacks -%%============================================================================== - -command(State) -> - Funs0 = [ {F, list_to_atom(atom_to_list(F) ++ "_args")} - || {F, _} <- ?MODULE:module_info(exports) - ], - - Funs1 = [ X || {_, FArgs} = X <- Funs0, - erlang:function_exported(?MODULE, FArgs, 1) - ], - proper_types:oneof([ {call, ?MODULE, F, ?MODULE:FArgs(State)} - || {F, FArgs} <- Funs1 - ]). - -precondition(S, {call, M, F, Args}) -> - Pre = list_to_atom(atom_to_list(F) ++ "_pre"), - case erlang:function_exported(M, Pre, 1) of - true -> M:Pre(S); - false -> true - end - andalso - case erlang:function_exported(M, Pre, 2) of - true -> M:Pre(S, Args); - false -> true - end. - -next_state(S, Res, {call, M, F, Args}) -> - Next = list_to_atom(atom_to_list(F) ++ "_next"), - case erlang:function_exported(M, Next, 3) of - true -> M:Next(S, Res, Args); - false -> S - end. - -postcondition(S, {call, M, F, Args}, Res) -> - Post = list_to_atom(atom_to_list(F) ++ "_post"), - case erlang:function_exported(M, Post, 3) of - true -> M:Post(S, Args, Res); - false -> true - end. - -%%============================================================================== -%% create_user -%%============================================================================== - -create_user(PetstoreUser) -> - petstore_api:create_user(PetstoreUser). - -create_user_args(S) -> - Args = [petstore_user:petstore_user()], - case erlang:function_exported(?MODULE, 'create_user_args_custom', 2) of - true -> ?MODULE:create_user_args_custom(S, Args); - false -> Args - end. - -%%============================================================================== -%% create_users_with_array_input -%%============================================================================== - -create_users_with_array_input(PetstoreUserArray) -> - petstore_api:create_users_with_array_input(PetstoreUserArray). - -create_users_with_array_input_args(S) -> - Args = [list(petstore_user:petstore_user())], - case erlang:function_exported(?MODULE, 'create_users_with_array_input_args_custom', 2) of - true -> ?MODULE:create_users_with_array_input_args_custom(S, Args); - false -> Args - end. - -%%============================================================================== -%% create_users_with_list_input -%%============================================================================== - -create_users_with_list_input(PetstoreUserArray) -> - petstore_api:create_users_with_list_input(PetstoreUserArray). - -create_users_with_list_input_args(S) -> - Args = [list(petstore_user:petstore_user())], - case erlang:function_exported(?MODULE, 'create_users_with_list_input_args_custom', 2) of - true -> ?MODULE:create_users_with_list_input_args_custom(S, Args); - false -> Args - end. - -%%============================================================================== -%% delete_user -%%============================================================================== - -delete_user(Username) -> - petstore_api:delete_user(Username). - -delete_user_args(S) -> - Args = [binary()], - case erlang:function_exported(?MODULE, 'delete_user_args_custom', 2) of - true -> ?MODULE:delete_user_args_custom(S, Args); - false -> Args - end. - -%%============================================================================== -%% get_user_by_name -%%============================================================================== - -get_user_by_name(Username) -> - petstore_api:get_user_by_name(Username). - -get_user_by_name_args(S) -> - Args = [binary()], - case erlang:function_exported(?MODULE, 'get_user_by_name_args_custom', 2) of - true -> ?MODULE:get_user_by_name_args_custom(S, Args); - false -> Args - end. - -%%============================================================================== -%% login_user -%%============================================================================== - -login_user(Username, Password) -> - petstore_api:login_user(Username, Password). - -login_user_args(S) -> - Args = [binary(), binary()], - case erlang:function_exported(?MODULE, 'login_user_args_custom', 2) of - true -> ?MODULE:login_user_args_custom(S, Args); - false -> Args - end. - -%%============================================================================== -%% logout_user -%%============================================================================== - -logout_user() -> - petstore_api:logout_user(). - -logout_user_args(S) -> - Args = [], - case erlang:function_exported(?MODULE, 'logout_user_args_custom', 2) of - true -> ?MODULE:logout_user_args_custom(S, Args); - false -> Args - end. - -%%============================================================================== -%% update_user -%%============================================================================== - -update_user(Username, PetstoreUser) -> - petstore_api:update_user(Username, PetstoreUser). - -update_user_args(S) -> - Args = [binary(), petstore_user:petstore_user()], - case erlang:function_exported(?MODULE, 'update_user_args_custom', 2) of - true -> ?MODULE:update_user_args_custom(S, Args); - false -> Args - end. - +-include("petstore_statem.hrl"). %%============================================================================== %% The statem's property @@ -193,7 +40,100 @@ prop_main() -> ). %%============================================================================== -%% Include file with setup, cleanup, initial_state -%% and state transitions callbacks +%% Setup %%============================================================================== --include("petstore_statem.hrl"). + +setup() -> ok. + +%%============================================================================== +%% Cleanup +%%============================================================================== + +cleanup() -> ok. + +%%============================================================================== +%% Initial State +%%============================================================================== + +initial_state() -> #{}. + +%%============================================================================== +%% create_user +%%============================================================================== + +create_user(PetstoreUser) -> + petstore_api:create_user(PetstoreUser). + +create_user_args(_S) -> + [petstore_user:petstore_user()]. + +%%============================================================================== +%% create_users_with_array_input +%%============================================================================== + +create_users_with_array_input(PetstoreUserArray) -> + petstore_api:create_users_with_array_input(PetstoreUserArray). + +create_users_with_array_input_args(_S) -> + [list(petstore_user:petstore_user())]. + +%%============================================================================== +%% create_users_with_list_input +%%============================================================================== + +create_users_with_list_input(PetstoreUserArray) -> + petstore_api:create_users_with_list_input(PetstoreUserArray). + +create_users_with_list_input_args(_S) -> + [list(petstore_user:petstore_user())]. + +%%============================================================================== +%% delete_user +%%============================================================================== + +delete_user(Username) -> + petstore_api:delete_user(Username). + +delete_user_args(_S) -> + [binary()]. + +%%============================================================================== +%% get_user_by_name +%%============================================================================== + +get_user_by_name(Username) -> + petstore_api:get_user_by_name(Username). + +get_user_by_name_args(_S) -> + [binary()]. + +%%============================================================================== +%% login_user +%%============================================================================== + +login_user(Username, Password) -> + petstore_api:login_user(Username, Password). + +login_user_args(_S) -> + [binary(), binary()]. + +%%============================================================================== +%% logout_user +%%============================================================================== + +logout_user() -> + petstore_api:logout_user(). + +logout_user_args(_S) -> + []. + +%%============================================================================== +%% update_user +%%============================================================================== + +update_user(Username, PetstoreUser) -> + petstore_api:update_user(Username, PetstoreUser). + +update_user_args(_S) -> + [binary(), petstore_user:petstore_user()]. + diff --git a/samples/client/petstore/erlang-proper/src/petstore_statem.hrl b/samples/client/petstore/erlang-proper/src/petstore_statem.hrl index 7b4dd931aa3..ab137181671 100644 --- a/samples/client/petstore/erlang-proper/src/petstore_statem.hrl +++ b/samples/client/petstore/erlang-proper/src/petstore_statem.hrl @@ -1,25 +1,49 @@ %%============================================================================== -%% Setup +%% Syntactic sugar %%============================================================================== -setup() -> ok. +command(State) -> + Funs0 = [ {F, list_to_atom(atom_to_list(F) ++ "_args")} + || {F, _} <- ?MODULE:module_info(exports) + ], -%%============================================================================== -%% Cleanup -%%============================================================================== + Funs1 = [ X || {_, FArgs} = X <- Funs0, + erlang:function_exported(?MODULE, FArgs, 1) + ], -cleanup() -> ok. + WeightFun = case erlang:function_exported(?MODULE, weight, 1) of + true -> fun ?MODULE:weight/1; + false -> fun(_) -> 1 end + end, -%%============================================================================== -%% Initial State -%%============================================================================== + proper_types:frequency([ { WeightFun(F) + , {call, ?MODULE, F, ?MODULE:FArgs(State)} + } + || {F, FArgs} <- Funs1 + ]). -initial_state() -> #{}. +precondition(S, {call, M, F, Args}) -> + Pre = list_to_atom(atom_to_list(F) ++ "_pre"), + case erlang:function_exported(M, Pre, 1) of + true -> M:Pre(S); + false -> true + end + andalso + case erlang:function_exported(M, Pre, 2) of + true -> M:Pre(S, Args); + false -> true + end. -%%============================================================================== -%% State transitions callbacks -%% -%% operation_pre(State) -> true. -%% operation_next(State, Result, Args) -> State. -%% operation_post(State, Args, Result) -> true. -%%============================================================================== +next_state(S, Res, {call, M, F, Args}) -> + Next = list_to_atom(atom_to_list(F) ++ "_next"), + case erlang:function_exported(M, Next, 3) of + true -> M:Next(S, Res, Args); + false -> S + end. + +postcondition(S, {call, M, F, Args}, Res) -> + Post = list_to_atom(atom_to_list(F) ++ "_post"), + case erlang:function_exported(M, Post, 3) of + true -> M:Post(S, Args, Res); + false -> true + end.