mirror of
https://github.com/valitydev/openapi-generator.git
synced 2024-11-07 10:58:55 +00:00
Introduce optional weight function for commands and other improvements (#1618)
* Generator erlang-proper Used to generate PropEr generators for property-based testing * Rearrange *_statem.erl functions and remove *_statem.hrl * Optional weight function * Optional argument to override generated values * Export function with arity 1 * Move syntactic sugar to header file * Only provide body when its allowed * The weight function should not depend on the state
This commit is contained in:
parent
5b91d40a8a
commit
87bc9d436f
@ -18,13 +18,20 @@
|
|||||||
Method = {{httpMethod}},
|
Method = {{httpMethod}},
|
||||||
Host = application:get_env({{packageName}}, host, "http://localhost:8080"),
|
Host = application:get_env({{packageName}}, host, "http://localhost:8080"),
|
||||||
Path = ["{{{replacedPathName}}}"],
|
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}},
|
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}}
|
{{^queryParams.isEmpty}}
|
||||||
QueryString = [{{#queryParams}}{{^-first}}, {{/-first}}<<"{{{baseName}}}=">>, {{{paramName}}}, <<"&">>{{/queryParams}}],
|
QueryString = [{{#queryParams}}{{^-first}}, {{/-first}}<<"{{{baseName}}}=">>, {{{paramName}}}, <<"&">>{{/queryParams}}],
|
||||||
{{/queryParams.isEmpty}}
|
{{/queryParams.isEmpty}}
|
||||||
|
|
||||||
|
{{#isBodyAllowed}}
|
||||||
{{packageName}}_utils:request(Method, [Host, ?BASE_URL, Path{{^queryParams.isEmpty}}, <<"?">>, QueryString{{/queryParams.isEmpty}}], jsx:encode(Body), ContentType).
|
{{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}}
|
{{/operation}}
|
||||||
{{/operations}}
|
{{/operations}}
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
-include("{{packageName}}.hrl").
|
-include("{{packageName}}.hrl").
|
||||||
|
|
||||||
-export([{{classname}}/0]).
|
-export([{{classname}}/0]).
|
||||||
|
{{^isEnum}}{{^isArrayModel}}
|
||||||
|
-export([{{classname}}/1]).
|
||||||
|
{{/isArrayModel}}{{/isEnum}}
|
||||||
-export_type([{{classname}}/0]).
|
-export_type([{{classname}}/0]).
|
||||||
|
|
||||||
-type {{classname}}() ::{{#isEnum}}
|
-type {{classname}}() ::{{#isEnum}}
|
||||||
@ -15,12 +17,23 @@
|
|||||||
| {{/-first}}{'{{name}}', {{dataType}} }{{/vars}}
|
| {{/-first}}{'{{name}}', {{dataType}} }{{/vars}}
|
||||||
].{{/isArrayModel}}{{/isEnum}}
|
].{{/isArrayModel}}{{/isEnum}}
|
||||||
|
|
||||||
{{classname}}() ->{{#isEnum}}
|
{{#isEnum}}
|
||||||
|
{{classname}}() ->
|
||||||
elements([{{#allowableValues.values}}{{^-first}}, {{/-first}}<<"{{.}}">>{{/allowableValues.values}}]).
|
elements([{{#allowableValues.values}}{{^-first}}, {{/-first}}<<"{{.}}">>{{/allowableValues.values}}]).
|
||||||
{{/isEnum}}{{#isArrayModel}}
|
{{/isEnum}}
|
||||||
list({{arrayModelType}}{{#minItems}}, {{minItems}}{{#maxItems}}, {{maxItems}}{{/maxItems}}{{/minItems}}).{{/isArrayModel}}{{^isEnum}}{{^isArrayModel}}
|
{{#isArrayModel}}
|
||||||
[ {{#vars}}{{^-first}}
|
{{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}}
|
, {{/-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}}
|
],
|
||||||
|
lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)).
|
||||||
|
{{/isArrayModel}}{{/isEnum}}
|
||||||
{{/model}}
|
{{/model}}
|
||||||
{{/models}}
|
{{/models}}
|
||||||
|
@ -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)
|
||||||
|
],
|
||||||
|
|
||||||
%%==============================================================================
|
Funs1 = [ X || {_, FArgs} = X <- Funs0,
|
||||||
%% Cleanup
|
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,
|
||||||
|
|
||||||
%%==============================================================================
|
proper_types:frequency([ { WeightFun(F)
|
||||||
%% Initial State
|
, {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.
|
||||||
|
|
||||||
%%==============================================================================
|
next_state(S, Res, {call, M, F, Args}) ->
|
||||||
%% State transitions callbacks
|
Next = list_to_atom(atom_to_list(F) ++ "_next"),
|
||||||
%%
|
case erlang:function_exported(M, Next, 3) of
|
||||||
%% operation_pre(State) -> true.
|
true -> M:Next(S, Res, Args);
|
||||||
%% operation_next(State, Result, Args) -> State.
|
false -> S
|
||||||
%% operation_post(State, Args, Result) -> true.
|
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.
|
||||||
|
@ -9,66 +9,7 @@
|
|||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
%%==============================================================================
|
-include("{{packageName}}_statem.hrl").
|
||||||
%% 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}}
|
|
||||||
|
|
||||||
%%==============================================================================
|
%%==============================================================================
|
||||||
%% The statem's property
|
%% The statem's property
|
||||||
@ -99,7 +40,34 @@ prop_main() ->
|
|||||||
).
|
).
|
||||||
|
|
||||||
%%==============================================================================
|
%%==============================================================================
|
||||||
%% Include file with setup, cleanup, initial_state
|
%% Setup
|
||||||
%% and state transitions callbacks
|
|
||||||
%%==============================================================================
|
%%==============================================================================
|
||||||
-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}}
|
2
samples/client/petstore/erlang-proper/.gitignore
vendored
Normal file
2
samples/client/petstore/erlang-proper/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
_build/
|
||||||
|
rebar.lock
|
@ -1 +1 @@
|
|||||||
3.3.0-SNAPSHOT
|
3.3.2-SNAPSHOT
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
-export([petstore_api_response/0]).
|
-export([petstore_api_response/0]).
|
||||||
|
|
||||||
|
-export([petstore_api_response/1]).
|
||||||
|
|
||||||
-export_type([petstore_api_response/0]).
|
-export_type([petstore_api_response/0]).
|
||||||
|
|
||||||
-type petstore_api_response() ::
|
-type petstore_api_response() ::
|
||||||
@ -12,8 +14,14 @@
|
|||||||
| {'message', binary() }
|
| {'message', binary() }
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
||||||
petstore_api_response() ->
|
petstore_api_response() ->
|
||||||
[ {'code', integer() }
|
petstore_api_response([]).
|
||||||
|
|
||||||
|
petstore_api_response(Fields) ->
|
||||||
|
Default = [ {'code', integer() }
|
||||||
, {'type', binary() }
|
, {'type', binary() }
|
||||||
, {'message', binary() }
|
, {'message', binary() }
|
||||||
].
|
],
|
||||||
|
lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)).
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
-export([petstore_category/0]).
|
-export([petstore_category/0]).
|
||||||
|
|
||||||
|
-export([petstore_category/1]).
|
||||||
|
|
||||||
-export_type([petstore_category/0]).
|
-export_type([petstore_category/0]).
|
||||||
|
|
||||||
-type petstore_category() ::
|
-type petstore_category() ::
|
||||||
@ -11,7 +13,13 @@
|
|||||||
| {'name', binary() }
|
| {'name', binary() }
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
||||||
petstore_category() ->
|
petstore_category() ->
|
||||||
[ {'id', integer() }
|
petstore_category([]).
|
||||||
|
|
||||||
|
petstore_category(Fields) ->
|
||||||
|
Default = [ {'id', integer() }
|
||||||
, {'name', binary() }
|
, {'name', binary() }
|
||||||
].
|
],
|
||||||
|
lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)).
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
-export([petstore_order/0]).
|
-export([petstore_order/0]).
|
||||||
|
|
||||||
|
-export([petstore_order/1]).
|
||||||
|
|
||||||
-export_type([petstore_order/0]).
|
-export_type([petstore_order/0]).
|
||||||
|
|
||||||
-type petstore_order() ::
|
-type petstore_order() ::
|
||||||
@ -15,11 +17,17 @@
|
|||||||
| {'complete', boolean() }
|
| {'complete', boolean() }
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
||||||
petstore_order() ->
|
petstore_order() ->
|
||||||
[ {'id', integer() }
|
petstore_order([]).
|
||||||
|
|
||||||
|
petstore_order(Fields) ->
|
||||||
|
Default = [ {'id', integer() }
|
||||||
, {'petId', integer() }
|
, {'petId', integer() }
|
||||||
, {'quantity', integer() }
|
, {'quantity', integer() }
|
||||||
, {'shipDate', datetime() }
|
, {'shipDate', datetime() }
|
||||||
, {'status', elements([<<"placed">>, <<"approved">>, <<"delivered">>]) }
|
, {'status', elements([<<"placed">>, <<"approved">>, <<"delivered">>]) }
|
||||||
, {'complete', boolean() }
|
, {'complete', boolean() }
|
||||||
].
|
],
|
||||||
|
lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)).
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
-export([petstore_pet/0]).
|
-export([petstore_pet/0]).
|
||||||
|
|
||||||
|
-export([petstore_pet/1]).
|
||||||
|
|
||||||
-export_type([petstore_pet/0]).
|
-export_type([petstore_pet/0]).
|
||||||
|
|
||||||
-type petstore_pet() ::
|
-type petstore_pet() ::
|
||||||
@ -15,11 +17,17 @@
|
|||||||
| {'status', binary() }
|
| {'status', binary() }
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
||||||
petstore_pet() ->
|
petstore_pet() ->
|
||||||
[ {'id', integer() }
|
petstore_pet([]).
|
||||||
|
|
||||||
|
petstore_pet(Fields) ->
|
||||||
|
Default = [ {'id', integer() }
|
||||||
, {'category', petstore_category:petstore_category() }
|
, {'category', petstore_category:petstore_category() }
|
||||||
, {'name', binary() }
|
, {'name', binary() }
|
||||||
, {'photoUrls', list(binary()) }
|
, {'photoUrls', list(binary()) }
|
||||||
, {'tags', list(petstore_tag:petstore_tag()) }
|
, {'tags', list(petstore_tag:petstore_tag()) }
|
||||||
, {'status', elements([<<"available">>, <<"pending">>, <<"sold">>]) }
|
, {'status', elements([<<"available">>, <<"pending">>, <<"sold">>]) }
|
||||||
].
|
],
|
||||||
|
lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)).
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
-export([petstore_tag/0]).
|
-export([petstore_tag/0]).
|
||||||
|
|
||||||
|
-export([petstore_tag/1]).
|
||||||
|
|
||||||
-export_type([petstore_tag/0]).
|
-export_type([petstore_tag/0]).
|
||||||
|
|
||||||
-type petstore_tag() ::
|
-type petstore_tag() ::
|
||||||
@ -11,7 +13,13 @@
|
|||||||
| {'name', binary() }
|
| {'name', binary() }
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
||||||
petstore_tag() ->
|
petstore_tag() ->
|
||||||
[ {'id', integer() }
|
petstore_tag([]).
|
||||||
|
|
||||||
|
petstore_tag(Fields) ->
|
||||||
|
Default = [ {'id', integer() }
|
||||||
, {'name', binary() }
|
, {'name', binary() }
|
||||||
].
|
],
|
||||||
|
lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)).
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
-export([petstore_user/0]).
|
-export([petstore_user/0]).
|
||||||
|
|
||||||
|
-export([petstore_user/1]).
|
||||||
|
|
||||||
-export_type([petstore_user/0]).
|
-export_type([petstore_user/0]).
|
||||||
|
|
||||||
-type petstore_user() ::
|
-type petstore_user() ::
|
||||||
@ -17,8 +19,12 @@
|
|||||||
| {'userStatus', integer() }
|
| {'userStatus', integer() }
|
||||||
].
|
].
|
||||||
|
|
||||||
|
|
||||||
petstore_user() ->
|
petstore_user() ->
|
||||||
[ {'id', integer() }
|
petstore_user([]).
|
||||||
|
|
||||||
|
petstore_user(Fields) ->
|
||||||
|
Default = [ {'id', integer() }
|
||||||
, {'username', binary() }
|
, {'username', binary() }
|
||||||
, {'firstName', binary() }
|
, {'firstName', binary() }
|
||||||
, {'lastName', binary() }
|
, {'lastName', binary() }
|
||||||
@ -26,4 +32,6 @@ petstore_user() ->
|
|||||||
, {'password', binary() }
|
, {'password', binary() }
|
||||||
, {'phone', binary() }
|
, {'phone', binary() }
|
||||||
, {'userStatus', integer() }
|
, {'userStatus', integer() }
|
||||||
].
|
],
|
||||||
|
lists:ukeymerge(1, lists:sort(Fields), lists:sort(Default)).
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ create_user(PetstoreUser) ->
|
|||||||
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user"],
|
Path = ["/user"],
|
||||||
Body = PetstoreUser,
|
Body = PetstoreUser,
|
||||||
ContentType = <<"text/plain">>,
|
ContentType = "text/plain",
|
||||||
|
|
||||||
petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType).
|
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"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user/createWithArray"],
|
Path = ["/user/createWithArray"],
|
||||||
Body = PetstoreUserArray,
|
Body = PetstoreUserArray,
|
||||||
ContentType = <<"text/plain">>,
|
ContentType = "text/plain",
|
||||||
|
|
||||||
petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType).
|
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"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user/createWithList"],
|
Path = ["/user/createWithList"],
|
||||||
Body = PetstoreUserArray,
|
Body = PetstoreUserArray,
|
||||||
ContentType = <<"text/plain">>,
|
ContentType = "text/plain",
|
||||||
|
|
||||||
petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType).
|
petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType).
|
||||||
|
|
||||||
@ -59,10 +59,8 @@ delete_user(Username) ->
|
|||||||
Method = delete,
|
Method = delete,
|
||||||
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user/", Username, ""],
|
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
|
%% @doc Get user by user name
|
||||||
%%
|
%%
|
||||||
@ -72,10 +70,8 @@ get_user_by_name(Username) ->
|
|||||||
Method = get,
|
Method = get,
|
||||||
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user/", Username, ""],
|
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
|
%% @doc Logs user into the system
|
||||||
%%
|
%%
|
||||||
@ -85,11 +81,9 @@ login_user(Username, Password) ->
|
|||||||
Method = get,
|
Method = get,
|
||||||
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user/login"],
|
Path = ["/user/login"],
|
||||||
Body = [],
|
|
||||||
ContentType = <<"text/plain">>,
|
|
||||||
QueryString = [<<"username=">>, Username, <<"&">>, <<"password=">>, Password, <<"&">>],
|
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
|
%% @doc Logs out current logged in user session
|
||||||
%%
|
%%
|
||||||
@ -99,10 +93,8 @@ logout_user() ->
|
|||||||
Method = get,
|
Method = get,
|
||||||
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user/logout"],
|
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
|
%% @doc Updated user
|
||||||
%% This can only be done by the logged in 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"),
|
Host = application:get_env(petstore, host, "http://localhost:8080"),
|
||||||
Path = ["/user/", Username, ""],
|
Path = ["/user/", Username, ""],
|
||||||
Body = PetstoreUser,
|
Body = PetstoreUser,
|
||||||
ContentType = <<"text/plain">>,
|
ContentType = "text/plain",
|
||||||
|
|
||||||
petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType).
|
petstore_utils:request(Method, [Host, ?BASE_URL, Path], jsx:encode(Body), ContentType).
|
||||||
|
|
||||||
|
@ -9,160 +9,7 @@
|
|||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
|
|
||||||
%%==============================================================================
|
-include("petstore_statem.hrl").
|
||||||
%% 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.
|
|
||||||
|
|
||||||
|
|
||||||
%%==============================================================================
|
%%==============================================================================
|
||||||
%% The statem's property
|
%% The statem's property
|
||||||
@ -193,7 +40,100 @@ prop_main() ->
|
|||||||
).
|
).
|
||||||
|
|
||||||
%%==============================================================================
|
%%==============================================================================
|
||||||
%% Include file with setup, cleanup, initial_state
|
%% Setup
|
||||||
%% and state transitions callbacks
|
|
||||||
%%==============================================================================
|
%%==============================================================================
|
||||||
-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()].
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
],
|
||||||
|
|
||||||
%%==============================================================================
|
Funs1 = [ X || {_, FArgs} = X <- Funs0,
|
||||||
%% Cleanup
|
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,
|
||||||
|
|
||||||
%%==============================================================================
|
proper_types:frequency([ { WeightFun(F)
|
||||||
%% Initial State
|
, {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.
|
||||||
|
|
||||||
%%==============================================================================
|
next_state(S, Res, {call, M, F, Args}) ->
|
||||||
%% State transitions callbacks
|
Next = list_to_atom(atom_to_list(F) ++ "_next"),
|
||||||
%%
|
case erlang:function_exported(M, Next, 3) of
|
||||||
%% operation_pre(State) -> true.
|
true -> M:Next(S, Res, Args);
|
||||||
%% operation_next(State, Result, Args) -> State.
|
false -> S
|
||||||
%% operation_post(State, Args, Result) -> true.
|
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.
|
||||||
|
Loading…
Reference in New Issue
Block a user