<commit_before>%% Copyright (c) 2013-2017 <NAME>. All Rights Reserved.
%% Use of this source code is governed by a BSD-style
%% license that can be found in the LICENSE file.

-module(re2_qc).

%% We aim to test the NIFs and not re2 itself, so the properties are only
%% concerned with making sure the Erlang interface works as documented. That
%% means, good properties to test re2 itself (not the NIFs) would probably
%% generate strings from a regex to match and use similar strategies for
%% replace/2.

-ifdef(TRIQ).
-include_lib("triq/include/triq.hrl").

prop_number() ->
    ?FORALL(Int, non_neg_integer(),
            begin
                N = list_to_binary(integer_to_list(Int)),
                {match, [N]} =:= re2:match(N, "^[0-9]+$")
            end).

prop_byte() ->
    ?FORALL(Byte, byte(),
            match =:= re2:match([Byte], "^.*", [{capture, none}])).

binary_str(Str) -> unicode:characters_to_binary(Str).

prop_char() ->
    ?FORALL(Char, unicode_char(),
            begin
                C = unicode:characters_to_binary([Char]),
                match =:= re2:match(C, "^.+$", [{capture, none}])
            end).

prop_string() ->
    ?FORALL(Str, ?LET(Size, choose(1,64), unicode_string(Size)),
            begin
                S = binary_str(Str),
                match =:= re2:match(S, "^.+$", [{capture, none}])
            end).

-define(REGEXES,
        [".*", "([0-7]+)[uUlL]*", "[a|b]", "h.*o", "(\\d+):(\\w+)"]).

-define(REGEXOPTS,
        [[{capture, none}],
         [{capture, all_but_first, binary}],
         [{capture, first, index}],
         [{capture, first, binary}],
         [{offset, 1}, {capture, all_but_first, binary}]]).

-define(STRINGS, ["12", "34", "hejsan", "foobar", "baz"]).

random_re_prop({M0, F0}, {M1, F1}) ->
    ?FORALL({Str,RE,Opts},
            {elements(?STRINGS), elements(?REGEXES), elements(?REGEXOPTS)},
            M0:F0(Str, RE, Opts) =:= M1:F1(Str, RE, Opts)).

prop_random_re2() ->
    random_re_prop({re2, match}, {re2, match}).

prop_random_re_vs_re2() ->
    random_re_prop({re, run}, {re2, match}).

-define(MIN_MEM, 1100).
-define(MAX_MEM, 2 bsl 30 - 1).
compile_options_static() -> elements(['caseless']).
compile_options_dynamic() -> ?LET(MaxMem, choose(?MIN_MEM, ?MAX_MEM),
                                  {'max_mem', MaxMem}).
compile_option() ->
    oneof([compile_options_static(), compile_options_dynamic()]).

prop_compile() ->
    ?FORALL({RE, Opts}, {elements(?REGEXES), [compile_option()]},
            {ok, <<>>} =:= re2:compile(RE, Opts)).

replace_options() ->
    elements([[], ['global']]).

prop_replace() ->
    ?FORALL({Str,RE,Replacement,Opts},
            {?LET(S, elements(?STRINGS), binary_str(S)),
             elements(?REGEXES),
             ?LET(S, unicode_string(), binary_str(S)),
             replace_options()},
            ?IMPLIES(not is_substr(Str, Replacement),
                     begin
                         case re2:match(Str, RE, [{capture, none}]) of
                             match ->
                                 Res = re2:replace(Str, RE, Replacement, Opts),<commit_msg>qc: const length sample string in prop_replace/0<commit_after>%% Copyright (c) 2013-2017 <NAME>. All Rights Reserved.
%% Use of this source code is governed by a BSD-style
%% license that can be found in the LICENSE file.

-module(re2_qc).

%% We aim to test the NIFs and not re2 itself, so the properties are only
%% concerned with making sure the Erlang interface works as documented. That
%% means, good properties to test re2 itself (not the NIFs) would probably
%% generate strings from a regex to match and use similar strategies for
%% replace/2.

-ifdef(TRIQ).
-include_lib("triq/include/triq.hrl").

prop_number() ->
    ?FORALL(Int, non_neg_integer(),
            begin
                N = list_to_binary(integer_to_list(Int)),
                {match, [N]} =:= re2:match(N, "^[0-9]+$")
            end).

prop_byte() ->
    ?FORALL(Byte, byte(),
            match =:= re2:match([Byte], "^.*", [{capture, none}])).

binary_str(Str) -> unicode:characters_to_binary(Str).

prop_char() ->
    ?FORALL(Char, unicode_char(),
            begin
                C = unicode:characters_to_binary([Char]),
                match =:= re2:match(C, "^.+$", [{capture, none}])
            end).

prop_string() ->
    ?FORALL(Str, ?LET(Size, choose(1,64), unicode_string(Size)),
            begin
                S = binary_str(Str),
                match =:= re2:match(S, "^.+$", [{capture, none}])
            end).

-define(REGEXES,
        [".*", "([0-7]+)[uUlL]*", "[a|b]", "h.*o", "(\\d+):(\\w+)"]).

-define(REGEXOPTS,
        [[{capture, none}],
         [{capture, all_but_first, binary}],
         [{capture, first, index}],
         [{capture, first, binary}],
         [{offset, 1}, {capture, all_but_first, binary}]]).

-define(STRINGS, ["12", "34", "hejsan", "foobar", "baz"]).

random_re_prop({M0, F0}, {M1, F1}) ->
    ?FORALL({Str,RE,Opts},
            {elements(?STRINGS), elements(?REGEXES), elements(?REGEXOPTS)},
            M0:F0(Str, RE, Opts) =:= M1:F1(Str, RE, Opts)).

prop_random_re2() ->
    random_re_prop({re2, match}, {re2, match}).

prop_random_re_vs_re2() ->
    random_re_prop({re, run}, {re2, match}).

-define(MIN_MEM, 1100).
-define(MAX_MEM, 2 bsl 30 - 1).
compile_options_static() -> elements(['caseless']).
compile_options_dynamic() -> ?LET(MaxMem, choose(?MIN_MEM, ?MAX_MEM),
                                  {'max_mem', MaxMem}).
compile_option() ->
    oneof([compile_options_static(), compile_options_dynamic()]).

prop_compile() ->
    ?FORALL({RE, Opts}, {elements(?REGEXES), [compile_option()]},
            {ok, <<>>} =:= re2:compile(RE, Opts)).

replace_options() ->
    elements([[], ['global']]).

prop_replace() ->
    ?FORALL({Str,RE,Replacement,Opts},
            {?LET(S, elements(?STRINGS), binary_str(S)),
             elements(?REGEXES),
             ?LET(S, unicode_string(64), binary_str(S)),
             replace_options()},
            ?IMPLIES(not is_substr(Str, Replacement),
                     begin
                         case re2:match(Str, RE, [{capture, none}]) of
                             match ->
                                 Res = re2:replace(Str, RE, Replacement, Opts),
{'fraction_non_alphanumeric': 0.1843745007189647, 'fraction_numerical': 0.017095382648985462, 'mean_word_length': 2.577142857142857, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7081503', 'n_tokens_mistral': 2180, 'n_tokens_neox': 2067, 'n_words': 469}