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) -r logs
|
||||
|
||||
.PHONY: clean-tests
|
||||
clean-tests:
|
||||
@ rm -rf _build/test/lib
|
||||
# Docs
|
||||
|
||||
.PHONY: docs
|
||||
@ -53,10 +56,14 @@ test: eunit ct xref dialyzer cover
|
||||
|
||||
.PHONY: eunit
|
||||
eunit:
|
||||
@ $(MAKE) clean-tests
|
||||
$(REBAR) eunit
|
||||
|
||||
# @ rm -rf _build
|
||||
|
||||
.PHONY: ct
|
||||
ct: test/JSON-Schema-Test-Suite/tests
|
||||
@ $(MAKE) clean-tests
|
||||
$(REBAR) ct
|
||||
|
||||
.PHONY: xref
|
||||
@ -73,4 +80,5 @@ elvis:
|
||||
|
||||
.PHONY: cover
|
||||
cover:
|
||||
@ $(MAKE) clean-tests
|
||||
$(REBAR) cover -v
|
||||
|
@ -56,7 +56,8 @@
|
||||
|
||||
-type error_type() :: atom()
|
||||
| {atom(), jesse:json_term()}
|
||||
| {atom(), binary()}.
|
||||
| {atom(), binary()}
|
||||
| {atom(), [error_reason()]}.
|
||||
|
||||
%% Includes
|
||||
-include("jesse_schema_validator.hrl").
|
||||
|
@ -122,6 +122,7 @@
|
||||
-define(any_schemas_not_valid, 'any_schemas_not_valid').
|
||||
-define(not_multiple_of, 'not_multiple_of').
|
||||
-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(wrong_not_schema, 'wrong_not_schema').
|
||||
-define(external, 'external').
|
||||
|
@ -60,6 +60,7 @@
|
||||
| ?not_in_range
|
||||
| ?not_multiple_of
|
||||
| ?not_one_schema_valid
|
||||
| ?more_than_one_schema_valid
|
||||
| ?not_schema_valid
|
||||
| ?too_few_properties
|
||||
| ?too_many_properties
|
||||
@ -69,7 +70,8 @@
|
||||
| ?external.
|
||||
|
||||
-type data_error_type() :: data_error()
|
||||
| {data_error(), binary()}.
|
||||
| {data_error(), binary()}
|
||||
| {data_error(), [jesse_error:error_reason()]}.
|
||||
|
||||
%%% API
|
||||
%% @doc Goes through attributes of the given schema `JsonSchema' and
|
||||
@ -1111,8 +1113,10 @@ check_all_of_(_Value, [], State) ->
|
||||
State;
|
||||
check_all_of_(Value, [Schema | Schemas], State) ->
|
||||
case validate_schema(Value, Schema, State) of
|
||||
{true, NewState} -> check_all_of_(Value, Schemas, NewState);
|
||||
{false, _} -> handle_data_invalid(?all_schemas_not_valid, Value, State)
|
||||
{true, NewState} ->
|
||||
check_all_of_(Value, Schemas, NewState);
|
||||
{false, Errors} ->
|
||||
handle_data_invalid({?all_schemas_not_valid, Errors}, Value, State)
|
||||
end.
|
||||
|
||||
%% @doc 5.5.4. anyOf
|
||||
@ -1132,21 +1136,28 @@ check_all_of_(Value, [Schema | Schemas], State) ->
|
||||
%%
|
||||
%% @private
|
||||
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) ->
|
||||
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);
|
||||
check_any_of_(Value, [Schema | Schemas], State) ->
|
||||
NumErrsBefore = length(jesse_state:get_error_list(State)),
|
||||
check_any_of_(Value, [], State, Errors) ->
|
||||
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
|
||||
{true, NewState} ->
|
||||
case length(jesse_state:get_error_list(NewState)) of
|
||||
NumErrsBefore -> NewState;
|
||||
_ -> check_any_of_(Value, Schemas, State)
|
||||
end;
|
||||
{false, _} -> check_any_of_(Value, Schemas, State)
|
||||
ErrorsAfter = jesse_state:get_error_list(NewState),
|
||||
case length(ErrorsAfter) of
|
||||
NumErrsBefore -> NewState;
|
||||
_ ->
|
||||
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.
|
||||
|
||||
%% @doc 5.5.5. oneOf
|
||||
@ -1166,29 +1177,33 @@ check_any_of_(Value, [Schema | Schemas], State) ->
|
||||
%%
|
||||
%% @private
|
||||
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) ->
|
||||
handle_schema_invalid(?wrong_one_of_schema_array, State).
|
||||
|
||||
check_one_of_(_Value, [], State, 1) ->
|
||||
check_one_of_(_Value, [], State, 1, _Errors) ->
|
||||
State;
|
||||
check_one_of_(Value, [], State, 0) ->
|
||||
handle_data_invalid(?not_one_schema_valid, Value, State);
|
||||
check_one_of_(Value, _Schemas, State, Valid) when Valid > 1 ->
|
||||
handle_data_invalid(?not_one_schema_valid, Value, State);
|
||||
check_one_of_(Value, [Schema | Schemas], State, Valid) ->
|
||||
NumErrsBefore = length(jesse_state:get_error_list(State)),
|
||||
check_one_of_(Value, [], State, 0, Errors) ->
|
||||
handle_data_invalid({?not_one_schema_valid, Errors}, Value, State);
|
||||
check_one_of_(Value, _Schemas, State, Valid, _Errors) when Valid > 1 ->
|
||||
handle_data_invalid(?more_than_one_schema_valid, Value, State);
|
||||
check_one_of_(Value, [Schema | Schemas], State, Valid, Errors) ->
|
||||
ErrorsBefore = jesse_state:get_error_list(State),
|
||||
NumErrsBefore = length(ErrorsBefore),
|
||||
case validate_schema(Value, Schema, State) of
|
||||
{true, NewState} ->
|
||||
case length(jesse_state:get_error_list(NewState)) of
|
||||
NumErrsBefore -> check_one_of_(Value, Schemas, NewState, Valid + 1);
|
||||
_ -> check_one_of_(Value, Schemas, State, Valid)
|
||||
end;
|
||||
{false, _} ->
|
||||
check_one_of_(Value, Schemas, State, Valid)
|
||||
ErrorsAfter = jesse_state:get_error_list(NewState),
|
||||
case length(ErrorsAfter) of
|
||||
NumErrsBefore ->
|
||||
check_one_of_(Value, Schemas, NewState, Valid + 1, Errors);
|
||||
_ ->
|
||||
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.
|
||||
|
||||
|
||||
%% @doc 5.5.6. not
|
||||
%%
|
||||
%% 5.5.6.1. Valid values
|
||||
@ -1380,3 +1395,14 @@ maybe_external_check_value(Value, State) ->
|
||||
Fun ->
|
||||
Fun(Value, State)
|
||||
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, [])
|
||||
).
|
||||
|
||||
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(COMMON_TEST). % see Emakefile
|
||||
map_schema_test() ->
|
||||
|
Loading…
Reference in New Issue
Block a user