<commit_before>-module(clojerl_LazySeq_SUITE).

-include("clojerl.hrl").

-export([all/0, init_per_suite/1]).

-export([ new/1
        , count/1
        , str/1
        , is_sequential/1
        , hash/1
        , seq/1
        , equiv/1
        , cons/1
        , complete_coverage/1
        ]).

-type config() :: list().
-type result() :: {comments, string()}.

-spec all() -> [atom()].
all() ->
  ExcludedFuns = [init_per_suite, end_per_suite, all, module_info],
  Exports = ?MODULE:module_info(exports),
  [F || {F, 1} <- Exports, not lists:member(F, ExcludedFuns)].

-spec init_per_suite(config()) -> config().
init_per_suite(Config) ->
  application:ensure_all_started(clojerl),
  Config.

%%------------------------------------------------------------------------------
%% Test Cases
%%------------------------------------------------------------------------------

-spec new(config()) -> result().
new(_Config) ->
  LazySeq3 = range(1, 3),
  [1, 2, 3] = clj_core:to_list(LazySeq3),

  LazySeq0 = range(1, 0),
  ?NIL = clj_core:seq(LazySeq0),

  {comments, ""}.

-spec count(config()) -> result().
count(_Config) ->
  LazySeq42 = range(1, 42),
  42 = clj_core:count(LazySeq42),

  LazySeq0 = range(1, 0),
  0 = clj_core:count(LazySeq0),

  {comments, ""}.

-spec str(config()) -> result().
str(_Config) ->
  Regex = <<"#<clojerl.LazySeq@\\d+>">>,
  LazySeq3 = range(1, 3),
  {match, _} = re:run(clj_core:str(LazySeq3), Regex),

  LazySeq0 = range(1, 0),
  {match, _} = re:run(clj_core:str(LazySeq0), Regex),
  <<"()">> = clj_core:str(clj_core:rest(LazySeq0)),

  {comments, ""}.

-spec is_sequential(config()) -> result().
is_sequential(_Config) ->
  LazySeq = range(1, 3),
  true = clj_core:'sequential?'(LazySeq),

  {comments, ""}.

-spec hash(config()) -> result().
hash(_Config) ->
  LazySeq1 = range(1, 4),
  LazySeq2 = range(1, 3),
  LazySeq3 = range(1.0, 3.0),

  Hash1 = 'clojerl.IHash':hash(LazySeq1),
  Hash2 = 'clojerl.IHash':hash(LazySeq2),
  Hash3 = 'clojerl.IHash':hash(LazySeq3),

  true = Hash1 =/= Hash2,
  true = Hash2 =/= Hash3,

  {comments, ""}.

-spec seq(config()) -> result().
seq(_Config) ->
  LazySeq = range(1, 3),
  1 = clj_core:first(LazySeq),
  2 = clj_core:first(clj_core:next(LazySeq)),
  3 = clj_core:first(clj_core:next(clj_core:next(LazySeq))),

  LazySeq1 = range(1, 1),
  1 = clj_core:first(LazySeq1),
  ?NIL = clj_core:next(LazySeq1),
  [] = clj_core:to_list(clj_core:rest(LazySeq1)),
  ?NIL = clj_core:seq(clj_core:rest(LazySeq1)),

  LazySeq0  = range(1, 0),
  ?NIL = clj_core:first(LazySeq0),
  ?NIL = clj_core:next(LazySeq0),
  true = ?NIL =/= clj_core:rest(LazySeq0),
  ?NIL = clj_core:seq(clj_core:rest(LazySeq0)),

  LazySeqBis = 'clojerl.LazySeq':?CONSTRUCTOR(fun([]) -> range(1, 3) end),
  1 = clj_core:first(LazySeqBis),
  2 = clj_core:first(clj_core:rest(LazySeqBis)),
  3 = clj_core:first(clj_core:next(clj_core:next(LazySeqBis))),
  [1, 2, 3] = clj_core:to_list(clj_core:seq(LazySeqBis)),

  {comments, ""}.

-spec equiv(config()) -> result().
equiv(_Config) ->
  ct:comment("Check that lazy seqs with the same elements are equivalent"),
  LazySeq1 = clj_core:with_meta(range(1, 3), #{a => 1}),
  LazySeq2 = clj_core:with_meta(range(1, 3), #{b => 2}),
  true = clj_core:equiv(LazySeq1, LazySeq2),

  ct:comment("Check that a lazy seq and a list with the "
             "same elements are equivalent"),
  true = clj_core:equiv(LazySeq1, [1, 2, 3]),

  ct:comment("Check that lists with the same elements are not equivalent"),
  LazySeq3 = clj_core:with_meta(range(1, 4), #{c => 3}),
  false = clj_core:equiv(LazySeq1, LazySeq3),

  ct:comment("A clojerl.List and something else"),
  false = clj_core:equiv(LazySeq1, whatever),
  false = clj_core:equiv(LazySeq1, #{}),

  {comments, ""}.

-spec cons(config()) -> result().
cons(_Config) ->
  LazySeq = range(2, 2),

  ct:comment("Conj an element to a one element lazy seq"),
  TwoList = clj_core:conj(LazySeq, 1),

  2    = clj_core:count(TwoList),
  true = clj_core:equiv(clj_core:to_list(TwoList), [1, 2]),

  ct:comment("Conj an element to a list with one element"),
  ThreeList = clj_core:conj(TwoList, 0),

  3    = clj_core:count(ThreeList),
  true = clj_core:equiv(clj_core:to_list(ThreeList), [0, 1, 2]),

  {comments, ""}.

-spec complete_coverage(config()) -> result().
complete_coverage(_Config) ->
  ?NIL = 'clojerl.LazySeq':'_'(?NIL),<commit_msg>[#224] Improve coverage of clojerl.LazySeq<commit_after>-module(clojerl_LazySeq_SUITE).

-include("clojerl.hrl").

-export([all/0, init_per_suite/1]).

-export([ new/1
        , count/1
        , str/1
        , is_sequential/1
        , hash/1
        , seq/1
        , equiv/1
        , cons/1
        , reduce/1
        , complete_coverage/1
        ]).

-clojure(true).

-type config() :: list().
-type result() :: {comments, string()}.

-spec all() -> [atom()].
all() ->
  ExcludedFuns = [init_per_suite, end_per_suite, all, module_info],
  Exports = ?MODULE:module_info(exports),
  [F || {F, 1} <- Exports, not lists:member(F, ExcludedFuns)].

-spec init_per_suite(config()) -> config().
init_per_suite(Config) ->
  application:ensure_all_started(clojerl),
  Config.

%%------------------------------------------------------------------------------
%% Test Cases
%%------------------------------------------------------------------------------

-spec new(config()) -> result().
new(_Config) ->
  LazySeq3 = range(1, 3),
  [1, 2, 3] = clj_core:to_list(LazySeq3),

  LazySeq0 = range(1, 0),
  ?NIL = clj_core:seq(LazySeq0),

  {comments, ""}.

-spec count(config()) -> result().
count(_Config) ->
  LazySeq42 = range(1, 42),
  42 = clj_core:count(LazySeq42),

  LazySeq0 = range(1, 0),
  0 = clj_core:count(LazySeq0),

  {comments, ""}.

-spec str(config()) -> result().
str(_Config) ->
  Regex = <<"#<clojerl.LazySeq@\\d+>">>,
  LazySeq3 = range(1, 3),
  {match, _} = re:run(clj_core:str(LazySeq3), Regex),

  LazySeq0 = range(1, 0),
  {match, _} = re:run(clj_core:str(LazySeq0), Regex),
  <<"()">> = clj_core:str(clj_core:rest(LazySeq0)),

  {comments, ""}.

-spec is_sequential(config()) -> result().
is_sequential(_Config) ->
  LazySeq = range(1, 3),
  true = clj_core:'sequential?'(LazySeq),

  {comments, ""}.

-spec hash(config()) -> result().
hash(_Config) ->
  LazySeq1 = range(1, 4),
  LazySeq2 = range(1, 3),
  LazySeq3 = range(1.0, 3.0),

  Hash1 = 'clojerl.IHash':hash(LazySeq1),
  Hash2 = 'clojerl.IHash':hash(LazySeq2),
  Hash3 = 'clojerl.IHash':hash(LazySeq3),

  true = Hash1 =/= Hash2,
  true = Hash2 =/= Hash3,

  {comments, ""}.

-spec seq(config()) -> result().
seq(_Config) ->
  LazySeq = range(1, 3),
  1 = clj_core:first(LazySeq),
  2 = clj_core:first(clj_core:next(LazySeq)),
  3 = clj_core:first(clj_core:next(clj_core:next(LazySeq))),

  LazySeq1 = range(1, 1),
  1 = clj_core:first(LazySeq1),
  ?NIL = clj_core:next(LazySeq1),
  [] = clj_core:to_list(clj_core:rest(LazySeq1)),
  ?NIL = clj_core:seq(clj_core:rest(LazySeq1)),

  LazySeq0  = range(1, 0),
  ?NIL = clj_core:first(LazySeq0),
  ?NIL = clj_core:next(LazySeq0),
  true = ?NIL =/= clj_core:rest(LazySeq0),
  ?NIL = clj_core:seq(clj_core:rest(LazySeq0)),

  LazySeqBis = 'clojerl.LazySeq':?CONSTRUCTOR(fun([]) -> range(1, 3) end),
  1 = clj_core:first(LazySeqBis),
  2 = clj_core:first(clj_core:rest(LazySeqBis)),
  3 = clj_core:first(clj_core:next(clj_core:next(LazySeqBis))),
  [1, 2, 3] = clj_core:to_list(clj_core:seq(LazySeqBis)),

  {comments, ""}.

-spec equiv(config()) -> result().
equiv(_Config) ->
  ct:comment("Check that lazy seqs with the same elements are equivalent"),
  LazySeq1 = clj_core:with_meta(range(1, 3), #{a => 1}),
  LazySeq2 = clj_core:with_meta(range(1, 3), #{b => 2}),
  true = clj_core:equiv(LazySeq1, LazySeq2),

  ct:comment("Check that a lazy seq and a list with the "
             "same elements are equivalent"),
  true = clj_core:equiv(LazySeq1, [1, 2, 3]),

  ct:comment("Check that lists with the same elements are not equivalent"),
  LazySeq3 = clj_core:with_meta(range(1, 4), #{c => 3}),
  false = clj_core:equiv(LazySeq1, LazySeq3),

  ct:comment("A clojerl.List and something else"),
  false = clj_core:equiv(LazySeq1, whatever),
  false = clj_core:equiv(LazySeq1, #{}),

  {comments, ""}.

-spec cons(config()) -> result().
cons(_Config) ->
  LazySeq = range(2, 2),

  ct:comment("Conj an element to a one element lazy seq"),
  TwoList = clj_core:conj(LazySeq, 1),

  2    = clj_core:count(TwoList),
  true = clj_core:equiv(clj_core:to_list(TwoList), [1, 2]),

  ct:comment("Conj an element to a list with one element"),
  ThreeList = clj_core:conj(TwoList, 0),

  3    = clj_core:count(ThreeList),
  true = clj_core:equiv(clj_core:to_list(ThreeList), [0, 1, 2]),

  {comments, ""}.

-spec reduce(config()) -> result().
reduce(_Config) ->
  PlusFun = fun
              ([]) -> 0;
              ([X, Y]) -> X + Y
            end,
  EmptyLazySeq = range(1, 0),

  0  = 'clojerl.IReduce':reduce(EmptyLazySeq, PlusFun),
  42 = 'clojerl.IReduce':reduce(EmptyLazySeq, PlusFun, 42),

  TenLazySeq = range(1, 10),
  55 = 'clojerl.IReduce':reduce(TenLazySeq, PlusFun),
  60 = 'clojerl.IReduce':reduce(TenLazySeq, PlusFun, 5),

  PlusMaxFun = fun
                 ([]) -> 0;
                 ([X, Y]) when X < 10 -> X + Y;
                 ([X, _]) -> 'clojerl.Reduced':?CONSTRUCTOR(X)
            end,
  Reduced = 'clojerl.IReduce':reduce(TenLazySeq, PlusMaxFun),
  10 = clj_core:deref(Reduced),

  {comments, ""}.

-spec complete_coverage(config()) -> result().
complete_coverage(_Config) ->
  ?NIL = 'clojerl.LazySeq':'_'(?NIL),
{'fraction_non_alphanumeric': 0.21907162360848562, 'fraction_numerical': 0.029930686830497794, 'mean_word_length': 3.37035337310693, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1759846', 'n_tokens_mistral': 4036, 'n_tokens_neox': 3829, 'n_words': 680}