-
Notifications
You must be signed in to change notification settings - Fork 189
Expand file tree
/
Copy pathUnique.cpp
More file actions
137 lines (120 loc) · 4.37 KB
/
Copy pathUnique.cpp
File metadata and controls
137 lines (120 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <catch2/catch.hpp>
#include <rapidcheck/catch.h>
#include "Common.h"
using namespace rc;
using namespace rc::test;
namespace {
struct UniqueFactory {
template <typename Container, typename T>
static Gen<Container> makeGen(Gen<T> gen) {
return gen::unique<Container>(std::move(gen));
}
};
struct UniqueByFactory {
template <typename Container, typename T1, typename T2>
static Gen<Container> makeGen(Gen<std::pair<T1, T2>> gen) {
return gen::uniqueBy<Container>(
std::move(gen), [](const std::pair<T1, T2> &p) { return p.first; });
}
};
template <typename Factory>
struct UniqueByProperties {
template <typename T>
static void exec() {
templatedProp<T>(
"generated values are unique by key",
[](const GenParams ¶ms) {
const auto gen = Factory::template makeGen<T>(
gen::arbitrary<std::pair<int, int>>());
onAnyPath(
gen(params.random, params.size),
[](const Shrinkable<T> &value, const Shrinkable<T> &shrink) {
const auto v = value.value();
std::set<int> s;
for (const auto &x : v) {
s.insert(x.first);
}
RC_ASSERT(s.size() ==
std::size_t(std::distance(begin(v), end(v))));
});
});
templatedProp<T>(
"finds minimum where at least two elements must have keys than a "
"certain value",
[](const GenParams ¶ms) {
const auto gen = Factory::template makeGen<T>(
gen::arbitrary<std::pair<int, int>>());
const auto target = *gen::inRange(0, 10);
const auto result = searchGen(
params.random,
params.size,
gen,
[=](T elements) {
return std::count_if(begin(elements),
end(elements),
[=](const std::pair<int, int> &x) {
return x.first >= target;
}) >= 2;
});
using Set = std::set<std::pair<int, int>>;
RC_ASSERT((Set(begin(result), end(result)) ==
Set{{target + 1, 0}, {target, 0}}));
});
}
};
} // namespace
TEST_CASE("gen::uniqueBy") {
using Pair = std::pair<int, int>;
forEachType<UniqueByProperties<UniqueByFactory>,
RC_SEQUENCE_CONTAINERS(Pair)>();
}
namespace {
template <typename Factory>
struct UniqueProperties {
template <typename T>
static void exec() {
templatedProp<T>(
"generated values are unique",
[](const GenParams ¶ms) {
const auto gen = Factory::template makeGen<T>(gen::arbitrary<int>());
onAnyPath(
gen(params.random, params.size),
[](const Shrinkable<T> &value, const Shrinkable<T> &shrink) {
const auto v = value.value();
std::set<int> s(begin(v), end(v));
RC_ASSERT(s.size() ==
std::size_t(std::distance(begin(v), end(v))));
});
});
templatedProp<T>(
"finds minimum where at least two elements must have values greater "
"than a certain value",
[](const GenParams ¶ms) {
const auto gen = Factory::template makeGen<T>(gen::arbitrary<int>());
const auto target = *gen::inRange(0, 10);
const auto result = searchGen(
params.random,
params.size,
gen,
[=](T elements) {
return std::count_if(begin(elements),
end(elements),
[=](int x) { return x >= target; }) >= 2;
});
RC_ASSERT((std::set<int>(begin(result), end(result)) ==
std::set<int>{target + 1, target}));
});
}
};
} // namespace
TEST_CASE("gen::unique") {
forEachType<GenericProperties<UniqueFactory>,
RC_SEQUENCE_CONTAINERS(int),
std::basic_string<int>>();
forEachType<ParamsProperties<UniqueFactory>,
RC_SEQUENCE_CONTAINERS(GenParams)>();
forEachType<UniqueProperties<UniqueFactory>, RC_SEQUENCE_CONTAINERS(int)>();
forEachType<RetrialProperties<UniqueFactory>,
RC_SEQUENCE_CONTAINERS(int),
std::basic_string<int>>();
}