mirror of
https://github.com/valitydev/jesse.git
synced 2024-11-06 09:35:23 +00:00
Merge pull request #92 from jfacorro/90-improve-error-messages-one-of-return-all-messages
[#90] Improve error messages (alternative)
This commit is contained in:
commit
bf5ba4b644
8
Makefile
8
Makefile
@ -23,6 +23,9 @@ distclean:
|
|||||||
$(RM) doc/stylesheet.css
|
$(RM) doc/stylesheet.css
|
||||||
$(RM) -r logs
|
$(RM) -r logs
|
||||||
|
|
||||||
|
.PHONY: clean-tests
|
||||||
|
clean-tests:
|
||||||
|
@ rm -rf _build/test/lib
|
||||||
# Docs
|
# Docs
|
||||||
|
|
||||||
.PHONY: docs
|
.PHONY: docs
|
||||||
@ -53,10 +56,14 @@ test: eunit ct xref dialyzer cover
|
|||||||
|
|
||||||
.PHONY: eunit
|
.PHONY: eunit
|
||||||
eunit:
|
eunit:
|
||||||
|
@ $(MAKE) clean-tests
|
||||||
$(REBAR) eunit
|
$(REBAR) eunit
|
||||||
|
|
||||||
|
# @ rm -rf _build
|
||||||
|
|
||||||
.PHONY: ct
|
.PHONY: ct
|
||||||
ct: test/JSON-Schema-Test-Suite/tests
|
ct: test/JSON-Schema-Test-Suite/tests
|
||||||
|
@ $(MAKE) clean-tests
|
||||||
$(REBAR) ct
|
$(REBAR) ct
|
||||||
|
|
||||||
.PHONY: xref
|
.PHONY: xref
|
||||||
@ -73,4 +80,5 @@ elvis:
|
|||||||
|
|
||||||
.PHONY: cover
|
.PHONY: cover
|
||||||
cover:
|
cover:
|
||||||
|
@ $(MAKE) clean-tests
|
||||||
$(REBAR) cover -v
|
$(REBAR) cover -v
|
||||||
|
@ -56,7 +56,8 @@
|
|||||||
|
|
||||||
-type error_type() :: atom()
|
-type error_type() :: atom()
|
||||||
| {atom(), jesse:json_term()}
|
| {atom(), jesse:json_term()}
|
||||||
| {atom(), binary()}.
|
| {atom(), binary()}
|
||||||
|
| {atom(), [error_reason()]}.
|
||||||
|
|
||||||
%% Includes
|
%% Includes
|
||||||
-include("jesse_schema_validator.hrl").
|
-include("jesse_schema_validator.hrl").
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
-define(any_schemas_not_valid, 'any_schemas_not_valid').
|
-define(any_schemas_not_valid, 'any_schemas_not_valid').
|
||||||
-define(not_multiple_of, 'not_multiple_of').
|
-define(not_multiple_of, 'not_multiple_of').
|
||||||
-define(not_one_schema_valid, 'not_one_schema_valid').
|
-define(not_one_schema_valid, 'not_one_schema_valid').
|
||||||
|
-define(more_than_one_schema_valid, 'more_than_one_schema_valid').
|
||||||
-define(not_schema_valid, 'not_schema_valid').
|
-define(not_schema_valid, 'not_schema_valid').
|
||||||
-define(wrong_not_schema, 'wrong_not_schema').
|
-define(wrong_not_schema, 'wrong_not_schema').
|
||||||
-define(external, 'external').
|
-define(external, 'external').
|
||||||
|
@ -60,6 +60,7 @@
|
|||||||
| ?not_in_range
|
| ?not_in_range
|
||||||
| ?not_multiple_of
|
| ?not_multiple_of
|
||||||
| ?not_one_schema_valid
|
| ?not_one_schema_valid
|
||||||
|
| ?more_than_one_schema_valid
|
||||||
| ?not_schema_valid
|
| ?not_schema_valid
|
||||||
| ?too_few_properties
|
| ?too_few_properties
|
||||||
| ?too_many_properties
|
| ?too_many_properties
|
||||||
@ -69,7 +70,8 @@
|
|||||||
| ?external.
|
| ?external.
|
||||||
|
|
||||||
-type data_error_type() :: data_error()
|
-type data_error_type() :: data_error()
|
||||||
| {data_error(), binary()}.
|
| {data_error(), binary()}
|
||||||
|
| {data_error(), [jesse_error:error_reason()]}.
|
||||||
|
|
||||||
%%% API
|
%%% API
|
||||||
%% @doc Goes through attributes of the given schema `JsonSchema' and
|
%% @doc Goes through attributes of the given schema `JsonSchema' and
|
||||||
@ -1111,8 +1113,10 @@ check_all_of_(_Value, [], State) ->
|
|||||||
State;
|
State;
|
||||||
check_all_of_(Value, [Schema | Schemas], State) ->
|
check_all_of_(Value, [Schema | Schemas], State) ->
|
||||||
case validate_schema(Value, Schema, State) of
|
case validate_schema(Value, Schema, State) of
|
||||||
{true, NewState} -> check_all_of_(Value, Schemas, NewState);
|
{true, NewState} ->
|
||||||
{false, _} -> handle_data_invalid(?all_schemas_not_valid, Value, State)
|
check_all_of_(Value, Schemas, NewState);
|
||||||
|
{false, Errors} ->
|
||||||
|
handle_data_invalid({?all_schemas_not_valid, Errors}, Value, State)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc 5.5.4. anyOf
|
%% @doc 5.5.4. anyOf
|
||||||
@ -1132,21 +1136,28 @@ check_all_of_(Value, [Schema | Schemas], State) ->
|
|||||||
%%
|
%%
|
||||||
%% @private
|
%% @private
|
||||||
check_any_of(Value, [_ | _] = Schemas, State) ->
|
check_any_of(Value, [_ | _] = Schemas, State) ->
|
||||||
check_any_of_(Value, Schemas, State);
|
check_any_of_(Value, Schemas, State, empty);
|
||||||
check_any_of(_Value, _InvalidSchemas, State) ->
|
check_any_of(_Value, _InvalidSchemas, State) ->
|
||||||
handle_schema_invalid(?wrong_any_of_schema_array, State).
|
handle_schema_invalid(?wrong_any_of_schema_array, State).
|
||||||
|
|
||||||
check_any_of_(Value, [], State) ->
|
check_any_of_(Value, [], State, []) ->
|
||||||
handle_data_invalid(?any_schemas_not_valid, Value, State);
|
handle_data_invalid(?any_schemas_not_valid, Value, State);
|
||||||
check_any_of_(Value, [Schema | Schemas], State) ->
|
check_any_of_(Value, [], State, Errors) ->
|
||||||
NumErrsBefore = length(jesse_state:get_error_list(State)),
|
handle_data_invalid({?any_schemas_not_valid, Errors}, Value, State);
|
||||||
|
check_any_of_(Value, [Schema | Schemas], State, Errors) ->
|
||||||
|
ErrorsBefore = jesse_state:get_error_list(State),
|
||||||
|
NumErrsBefore = length(ErrorsBefore),
|
||||||
case validate_schema(Value, Schema, State) of
|
case validate_schema(Value, Schema, State) of
|
||||||
{true, NewState} ->
|
{true, NewState} ->
|
||||||
case length(jesse_state:get_error_list(NewState)) of
|
ErrorsAfter = jesse_state:get_error_list(NewState),
|
||||||
NumErrsBefore -> NewState;
|
case length(ErrorsAfter) of
|
||||||
_ -> check_any_of_(Value, Schemas, State)
|
NumErrsBefore -> NewState;
|
||||||
end;
|
_ ->
|
||||||
{false, _} -> check_any_of_(Value, Schemas, State)
|
NewErrors = ErrorsAfter -- ErrorsBefore,
|
||||||
|
check_any_of_(Value, Schemas, State, shortest(NewErrors, Errors))
|
||||||
|
end;
|
||||||
|
{false, NewErrors} ->
|
||||||
|
check_any_of_(Value, Schemas, State, shortest(NewErrors, Errors))
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc 5.5.5. oneOf
|
%% @doc 5.5.5. oneOf
|
||||||
@ -1166,29 +1177,33 @@ check_any_of_(Value, [Schema | Schemas], State) ->
|
|||||||
%%
|
%%
|
||||||
%% @private
|
%% @private
|
||||||
check_one_of(Value, [_ | _] = Schemas, State) ->
|
check_one_of(Value, [_ | _] = Schemas, State) ->
|
||||||
check_one_of_(Value, Schemas, State, 0);
|
check_one_of_(Value, Schemas, State, 0, []);
|
||||||
check_one_of(_Value, _InvalidSchemas, State) ->
|
check_one_of(_Value, _InvalidSchemas, State) ->
|
||||||
handle_schema_invalid(?wrong_one_of_schema_array, State).
|
handle_schema_invalid(?wrong_one_of_schema_array, State).
|
||||||
|
|
||||||
check_one_of_(_Value, [], State, 1) ->
|
check_one_of_(_Value, [], State, 1, _Errors) ->
|
||||||
State;
|
State;
|
||||||
check_one_of_(Value, [], State, 0) ->
|
check_one_of_(Value, [], State, 0, Errors) ->
|
||||||
handle_data_invalid(?not_one_schema_valid, Value, State);
|
handle_data_invalid({?not_one_schema_valid, Errors}, Value, State);
|
||||||
check_one_of_(Value, _Schemas, State, Valid) when Valid > 1 ->
|
check_one_of_(Value, _Schemas, State, Valid, _Errors) when Valid > 1 ->
|
||||||
handle_data_invalid(?not_one_schema_valid, Value, State);
|
handle_data_invalid(?more_than_one_schema_valid, Value, State);
|
||||||
check_one_of_(Value, [Schema | Schemas], State, Valid) ->
|
check_one_of_(Value, [Schema | Schemas], State, Valid, Errors) ->
|
||||||
NumErrsBefore = length(jesse_state:get_error_list(State)),
|
ErrorsBefore = jesse_state:get_error_list(State),
|
||||||
|
NumErrsBefore = length(ErrorsBefore),
|
||||||
case validate_schema(Value, Schema, State) of
|
case validate_schema(Value, Schema, State) of
|
||||||
{true, NewState} ->
|
{true, NewState} ->
|
||||||
case length(jesse_state:get_error_list(NewState)) of
|
ErrorsAfter = jesse_state:get_error_list(NewState),
|
||||||
NumErrsBefore -> check_one_of_(Value, Schemas, NewState, Valid + 1);
|
case length(ErrorsAfter) of
|
||||||
_ -> check_one_of_(Value, Schemas, State, Valid)
|
NumErrsBefore ->
|
||||||
end;
|
check_one_of_(Value, Schemas, NewState, Valid + 1, Errors);
|
||||||
{false, _} ->
|
_ ->
|
||||||
check_one_of_(Value, Schemas, State, Valid)
|
NewErrors = ErrorsAfter -- ErrorsBefore,
|
||||||
|
check_one_of_(Value, Schemas, State, Valid, Errors ++ NewErrors)
|
||||||
|
end;
|
||||||
|
{false, NewErrors} ->
|
||||||
|
check_one_of_(Value, Schemas, State, Valid, Errors ++ NewErrors)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
%% @doc 5.5.6. not
|
%% @doc 5.5.6. not
|
||||||
%%
|
%%
|
||||||
%% 5.5.6.1. Valid values
|
%% 5.5.6.1. Valid values
|
||||||
@ -1380,3 +1395,14 @@ maybe_external_check_value(Value, State) ->
|
|||||||
Fun ->
|
Fun ->
|
||||||
Fun(Value, State)
|
Fun(Value, State)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
-spec shortest(list() | empty, list() | empty) -> list() | empty.
|
||||||
|
shortest(X, empty) ->
|
||||||
|
X;
|
||||||
|
shortest(empty, Y) ->
|
||||||
|
Y;
|
||||||
|
shortest(X, Y) when length(X) < length(Y) ->
|
||||||
|
X;
|
||||||
|
shortest(_, Y) ->
|
||||||
|
Y.
|
||||||
|
@ -221,6 +221,73 @@ schema_unsupported_test() ->
|
|||||||
, jesse_schema_validator:validate(UnsupportedSchema, Json, [])
|
, jesse_schema_validator:validate(UnsupportedSchema, Json, [])
|
||||||
).
|
).
|
||||||
|
|
||||||
|
data_invalid_one_of_test() ->
|
||||||
|
IntegerSchema = {[{<<"type">>, <<"integer">>}]},
|
||||||
|
StringSchema = {[{<<"type">>, <<"string">>}]},
|
||||||
|
ObjectSchema = {[ {<<"type">>, <<"object">>}
|
||||||
|
, { <<"properties">>
|
||||||
|
, [ {<<"name">>, StringSchema}
|
||||||
|
, {<<"age">>, IntegerSchema}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
, {<<"additionalProperties">>, false}
|
||||||
|
]},
|
||||||
|
|
||||||
|
Schema = {[ {<<"$schema">>, <<"http://json-schema.org/draft-04/schema#">>}
|
||||||
|
, {<<"oneOf">>, [IntegerSchema, StringSchema, ObjectSchema]}
|
||||||
|
]},
|
||||||
|
|
||||||
|
Json = [ {<<"name">>, 42}
|
||||||
|
, {<<"age">>, <<"John">>}
|
||||||
|
],
|
||||||
|
|
||||||
|
?assertThrow(
|
||||||
|
[ { data_invalid
|
||||||
|
, Schema
|
||||||
|
, { not_one_schema_valid
|
||||||
|
, [ {data_invalid, IntegerSchema, wrong_type, Json, []}
|
||||||
|
, {data_invalid, StringSchema, wrong_type, Json, []}
|
||||||
|
, {data_invalid, StringSchema, wrong_type, 42, [<<"name">>]}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
, Json
|
||||||
|
, []
|
||||||
|
}],
|
||||||
|
jesse_schema_validator:validate(Schema, Json, [])
|
||||||
|
).
|
||||||
|
|
||||||
|
data_invalid_any_of_test() ->
|
||||||
|
IntegerSchema = {[{<<"type">>, <<"integer">>}]},
|
||||||
|
StringSchema = {[{<<"type">>, <<"string">>}]},
|
||||||
|
ObjectSchema = {[ {<<"type">>, <<"object">>}
|
||||||
|
, { <<"properties">>
|
||||||
|
, [ {<<"name">>, StringSchema}
|
||||||
|
, {<<"age">>, IntegerSchema}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
, {<<"additionalProperties">>, false}
|
||||||
|
]},
|
||||||
|
|
||||||
|
Schema = {[ {<<"$schema">>, <<"http://json-schema.org/draft-04/schema#">>}
|
||||||
|
, {<<"anyOf">>, [IntegerSchema, StringSchema, ObjectSchema]}
|
||||||
|
]},
|
||||||
|
|
||||||
|
Json = [ {<<"name">>, 42}
|
||||||
|
, {<<"age">>, <<"John">>}
|
||||||
|
],
|
||||||
|
|
||||||
|
?assertThrow(
|
||||||
|
[ { data_invalid
|
||||||
|
, Schema
|
||||||
|
, { any_schemas_not_valid
|
||||||
|
, [{data_invalid, IntegerSchema, wrong_type, Json, []}]
|
||||||
|
}
|
||||||
|
, Json
|
||||||
|
, []
|
||||||
|
}],
|
||||||
|
jesse_schema_validator:validate(Schema, Json, [])
|
||||||
|
).
|
||||||
|
|
||||||
-ifndef(erlang_deprecated_types).
|
-ifndef(erlang_deprecated_types).
|
||||||
-ifndef(COMMON_TEST). % see Emakefile
|
-ifndef(COMMON_TEST). % see Emakefile
|
||||||
map_schema_test() ->
|
map_schema_test() ->
|
||||||
|
Loading…
Reference in New Issue
Block a user