<commit_before>#include <catch.hpp>
#include <rapidcheck-catch.h>

#include "rapidcheck/gen/Transform.h"
#include "rapidcheck/gen/Create.h"

#include "util/GenUtils.h"
#include "util/Predictable.h"
#include "util/Generators.h"
#include "util/ShrinkableUtils.h"

using namespace rc;
using namespace rc::test;

TEST_CASE("gen::map") {
  prop("maps the shrinkable returned by the generator",
       [](const Shrinkable<int> &shrinkable) {
         const auto mapper = [](int x) { return x * x; };
         const auto mapped =
             gen::map(Gen<int>(fn::constant(shrinkable)), mapper)(Random(), 0);
         RC_ASSERT(shrinkable::map(shrinkable, mapper) == mapped);
       });

  prop("forwards the parameter to the generator",
       [](const GenParams &params) {
         const auto gen = gen::map(genPassedParams(),
                                   [](GenParams &&x) { return std::move(x); });
         RC_ASSERT(gen(params.random, params.size).value() == params);
       });

  SECTION("works with non-copyable types") {
    const auto value =
        gen::map(gen::arbitrary<NonCopyable>(),
                 [](NonCopyable &&nc) { return std::move(nc); })(Random(), 0)
            .value();
    REQUIRE(isArbitraryPredictable(value));
  }

  prop("uses gen::arbitrary if no generator is specified",
       [](const GenParams &params) {
         const auto value = gen::map<Predictable>([](Predictable &&x) {
           return std::move(x);
         })(params.random, params.size)
                                .value();
         RC_ASSERT(isArbitraryPredictable(value));
       });

  prop(
      "finds minimum where string represtation of unsigned integer must be"
      " longer than some value",
      [](const Random &random) {
        const auto gen =
            gen::map(gen::arbitrary<unsigned int>(),
                     [](unsigned int x) { return std::to_string(x); });
        const auto n = *gen::inRange(2, 7);
        std::string expected(n, '0');
        expected[0] = '1';
        const auto result =
            searchGen(random,
                      kNominalSize,
                      gen,
                      [=](const std::string &x) { return x.size() >= n; });
        RC_ASSERT(result == expected);
      });
}

TEST_CASE("gen::mapcat") {
  // It would be nice and all to test the monad laws here but since `Gen` is
  // only morally a monad because of random splitting, it's simpler this way
  prop("mapcats the returned shrinkables",
       [](Shrinkable<int> a, Shrinkable<int> b) {
         const auto expected = shrinkable::mapcat(
             a,
             [=](int x) {
               return shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); });
             });
         const auto gen = gen::mapcat<int>(
             fn::constant(a),
             [=](int x) -> Gen<std::pair<int, int>> {
               return fn::constant(shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); }));
             });
         const auto actual = gen(Random(), 0);

         RC_ASSERT(actual == expected);
       });

  prop("passes correct size",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genSize(),
             [](int x) {
               return gen::map(genSize(),
                               [=](int y) { return std::make_pair(x, y); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == std::make_pair(params.size, params.size));
       });

  prop("passes unique randoms",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genRandom(),
             [](const Random &x) {
               return gen::map(
                   genRandom(),
                   [=](Random &&y) { return std::make_pair(x, std::move(y)); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.first != value.second);
         RC_ASSERT(value.first != params.random);
         RC_ASSERT(value.second != params.random);
       });

  SECTION("works with non-copyable types") {
    const auto gen = gen::mapcat(gen::arbitrary<NonCopyable>(),
                                 [](NonCopyable &&x) {
                                   RC_ASSERT(isArbitraryPredictable(x));
                                   return gen::arbitrary<NonCopyable>();
                                 });
    const auto value = gen(Random(), 0).value();
    RC_ASSERT(isArbitraryPredictable(value));
  }<commit_msg>Change wording in gen::mapcat property<commit_after>#include <catch.hpp>
#include <rapidcheck-catch.h>

#include "rapidcheck/gen/Transform.h"
#include "rapidcheck/gen/Create.h"

#include "util/GenUtils.h"
#include "util/Predictable.h"
#include "util/Generators.h"
#include "util/ShrinkableUtils.h"

using namespace rc;
using namespace rc::test;

TEST_CASE("gen::map") {
  prop("maps the shrinkable returned by the generator",
       [](const Shrinkable<int> &shrinkable) {
         const auto mapper = [](int x) { return x * x; };
         const auto mapped =
             gen::map(Gen<int>(fn::constant(shrinkable)), mapper)(Random(), 0);
         RC_ASSERT(shrinkable::map(shrinkable, mapper) == mapped);
       });

  prop("forwards the parameter to the generator",
       [](const GenParams &params) {
         const auto gen = gen::map(genPassedParams(),
                                   [](GenParams &&x) { return std::move(x); });
         RC_ASSERT(gen(params.random, params.size).value() == params);
       });

  SECTION("works with non-copyable types") {
    const auto value =
        gen::map(gen::arbitrary<NonCopyable>(),
                 [](NonCopyable &&nc) { return std::move(nc); })(Random(), 0)
            .value();
    REQUIRE(isArbitraryPredictable(value));
  }

  prop("uses gen::arbitrary if no generator is specified",
       [](const GenParams &params) {
         const auto value = gen::map<Predictable>([](Predictable &&x) {
           return std::move(x);
         })(params.random, params.size)
                                .value();
         RC_ASSERT(isArbitraryPredictable(value));
       });

  prop(
      "finds minimum where string represtation of unsigned integer must be"
      " longer than some value",
      [](const Random &random) {
        const auto gen =
            gen::map(gen::arbitrary<unsigned int>(),
                     [](unsigned int x) { return std::to_string(x); });
        const auto n = *gen::inRange(2, 7);
        std::string expected(n, '0');
        expected[0] = '1';
        const auto result =
            searchGen(random,
                      kNominalSize,
                      gen,
                      [=](const std::string &x) { return x.size() >= n; });
        RC_ASSERT(result == expected);
      });
}

TEST_CASE("gen::mapcat") {
  // It would be nice and all to test the monad laws here but since `Gen` is
  // only morally a monad because of random splitting, it's simpler this way
  prop("mapcats the returned shrinkables",
       [](Shrinkable<int> a, Shrinkable<int> b) {
         const auto expected = shrinkable::mapcat(
             a,
             [=](int x) {
               return shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); });
             });
         const auto gen = gen::mapcat<int>(
             fn::constant(a),
             [=](int x) -> Gen<std::pair<int, int>> {
               return fn::constant(shrinkable::map(
                   b, [=](int y) { return std::make_pair(x, y); }));
             });
         const auto actual = gen(Random(), 0);

         RC_ASSERT(actual == expected);
       });

  prop("passes correct size",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genSize(),
             [](int x) {
               return gen::map(genSize(),
                               [=](int y) { return std::make_pair(x, y); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value == std::make_pair(params.size, params.size));
       });

  prop("passes unique random generators",
       [](const GenParams &params) {
         const auto gen = gen::mapcat(
             genRandom(),
             [](const Random &x) {
               return gen::map(
                   genRandom(),
                   [=](Random &&y) { return std::make_pair(x, std::move(y)); });
             });

         const auto value = gen(params.random, params.size).value();
         RC_ASSERT(value.first != value.second);
         RC_ASSERT(value.first != params.random);
         RC_ASSERT(value.second != params.random);
       });

  SECTION("works with non-copyable types") {
    const auto gen = gen::mapcat(gen::arbitrary<NonCopyable>(),
                                 [](NonCopyable &&x) {
                                   RC_ASSERT(isArbitraryPredictable(x));
                                   return gen::arbitrary<NonCopyable>();
                                 });
    const auto value = gen(Random(), 0).value();
    RC_ASSERT(isArbitraryPredictable(value));
  }
{'fraction_non_alphanumeric': 0.14937397931409907, 'fraction_numerical': 0.00195971692977681, 'mean_word_length': 1.9824675324675325, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '213952', 'n_tokens_mistral': 2722, 'n_tokens_neox': 2626, 'n_words': 635}