emqx/test/props/prop_emqx_base62.erl

73 lines
2.6 KiB
Erlang

%%--------------------------------------------------------------------
%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(prop_emqx_base62).
-include_lib("proper/include/proper.hrl").
%%--------------------------------------------------------------------
%% Properties
%%--------------------------------------------------------------------
prop_symmetric() ->
?FORALL(Data, raw_data(),
begin
Encoded = emqx_base62:encode(Data),
to_binary(Data) =:= emqx_base62:decode(Encoded)
end).
prop_size() ->
?FORALL(Data, binary(),
begin
Encoded = emqx_base62:encode(Data),
base62_size(Data, Encoded)
end).
%%--------------------------------------------------------------------
%% Helpers
%%--------------------------------------------------------------------
to_binary(Data) when is_list(Data) ->
unicode:characters_to_binary(Data);
to_binary(Data) when is_integer(Data) ->
integer_to_binary(Data);
to_binary(Data) when is_binary(Data) ->
Data.
base62_size(Data, Encoded) ->
DataSize = erlang:size(Data),
EncodedSize = erlang:size(Encoded),
case (DataSize * 8 rem 6) of
0 ->
%% Due to the particularity of base 62, 3 bytes data maybe encoded
%% as 4 bytes data or 5 bytes data, the encode size maybe in the
%% range between DataSize*4/3 and DataSize*8/3
RangeStart = DataSize div 3 * 4,
RangeEnd = DataSize div 3 * 8,
EncodedSize >= RangeStart andalso EncodedSize =< RangeEnd;
_Rem ->
RangeStart = DataSize * 8 div 6 + 1,
RangeEnd = DataSize * 8 div 6 * 2 + 1,
EncodedSize >= RangeStart andalso EncodedSize =< RangeEnd
end.
%%--------------------------------------------------------------------
%% Generators
%%--------------------------------------------------------------------
raw_data() ->
oneof([integer(), string(), binary()]).