1 #pragma once
2 
3 #include "rapidcheck/detail/Configuration.h"
4 #include "rapidcheck/Seq.h"
5 #include "rapidcheck/Shrinkable.h"
6 #include "rapidcheck/shrinkable/Create.h"
7 #include "rapidcheck/Maybe.h"
8 #include "rapidcheck/seq/Create.h"
9 #include "rapidcheck/detail/TestMetadata.h"
10 
11 #include "util/ArbitraryRandom.h"
12 
13 namespace rc {
14 
15 template <>
16 struct Arbitrary<detail::TestParams> {
17   static Gen<detail::TestParams> arbitrary() {
18     return gen::build<detail::TestParams>(
19         gen::set(&detail::TestParams::seed),
20         gen::set(&detail::TestParams::maxSuccess, gen::inRange(0, 100)),
21         gen::set(&detail::TestParams::maxSize, gen::inRange(0, 101)),
22         gen::set(&detail::TestParams::maxDiscardRatio, gen::inRange(0, 100)),
23         gen::set(&detail::TestParams::disableShrinking));
24   }
25 };
26 
27 template <>
28 struct Arbitrary<detail::Configuration> {
29   static Gen<detail::Configuration> arbitrary() {
30     return gen::build<detail::Configuration>(
31         gen::set(&detail::Configuration::testParams),
32         gen::set(&detail::Configuration::verboseProgress),
33         gen::set(&detail::Configuration::verboseShrinking),
34         gen::set(&detail::Configuration::reproduce));
35   }
36 };
37 
38 template <>
39 struct Arbitrary<detail::CaseResult::Type> {
40   static Gen<detail::CaseResult::Type> arbitrary() {
41     return gen::element(detail::CaseResult::Type::Success,
42                         detail::CaseResult::Type::Failure,
43                         detail::CaseResult::Type::Discard);
44   }
45 };
46 
47 template <>
48 struct Arbitrary<detail::CaseResult> {
49   static Gen<detail::CaseResult> arbitrary() {
50     return gen::build<detail::CaseResult>(
51         gen::set(&detail::CaseResult::type),
52         gen::set(&detail::CaseResult::description));
53   }
54 };
55 
56 template <>
57 struct Arbitrary<detail::Reproduce> {
58   static Gen<detail::Reproduce> arbitrary() {
59     return gen::build<detail::Reproduce>(
60         gen::set(&detail::Reproduce::random, test::trulyArbitraryRandom()),
61         gen::set(&detail::Reproduce::size, gen::inRange<int>(0, 200)),
62         gen::set(&detail::Reproduce::shrinkPath,
63                  gen::container<std::vector<std::size_t>>(
64                      gen::inRange<std::size_t>(0, 200))));
65   }
66 };
67 
68 template <>
69 struct Arbitrary<detail::SuccessResult> {
70   static Gen<detail::SuccessResult> arbitrary() {
71     return gen::build<detail::SuccessResult>(
72         gen::set(&detail::SuccessResult::numSuccess, gen::positive<int>()),
73         gen::set(&detail::SuccessResult::distribution,
74                  gen::container<detail::Distribution>(
75                      gen::scale(0.1, gen::arbitrary<detail::Tags>()),
76                      gen::arbitrary<int>())));
77   }
78 };
79 
80 template <>
81 struct Arbitrary<detail::FailureResult> {
82   static Gen<detail::FailureResult> arbitrary() {
83     return gen::build<detail::FailureResult>(
84         gen::set(&detail::FailureResult::numSuccess, gen::positive<int>()),
85         gen::set(&detail::FailureResult::description),
86         gen::set(&detail::FailureResult::reproduce),
87         gen::set(&detail::FailureResult::counterExample));
88   }
89 };
90 
91 template <>
92 struct Arbitrary<detail::GaveUpResult> {
93   static Gen<detail::GaveUpResult> arbitrary() {
94     return gen::build<detail::GaveUpResult>(
95         gen::set(&detail::GaveUpResult::numSuccess, gen::positive<int>()),
96         gen::set(&detail::GaveUpResult::description));
97   }
98 };
99 
100 template <>
101 struct Arbitrary<detail::Error> {
102   static Gen<detail::Error> arbitrary() {
103     return gen::build<detail::Error>(gen::set(&detail::Error::description));
104   }
105 };
106 
107 template <>
108 struct Arbitrary<detail::CaseDescription> {
109   static Gen<detail::CaseDescription> arbitrary() {
110     return gen::build<detail::CaseDescription>(
111         gen::set(&detail::CaseDescription::result),
112         gen::set(&detail::CaseDescription::tags),
113         gen::set(&detail::CaseDescription::example,
114                  gen::map<detail::Example>(
115                      [](detail::Example &&example)
116                          -> std::function<detail::Example()> {
117                            return fn::constant(std::move(example));
118                          })));
119   }
120 };
121 
122 template <>
123 struct Arbitrary<detail::TestMetadata> {
124   static Gen<detail::TestMetadata> arbitrary() {
125     return gen::build<detail::TestMetadata>(
126         gen::set(&detail::TestMetadata::id),
127         gen::set(&detail::TestMetadata::description));
128   }
129 };
130 
131 template <typename T>
132 struct Arbitrary<Seq<T>> {
133   static Gen<Seq<T>> arbitrary() {
134     return gen::map<std::vector<T>>(&seq::fromContainer<std::vector<T>>);
135   }
136 };
137 
138 template <typename T>
139 struct Arbitrary<Shrinkable<T>> {
140   static Gen<Shrinkable<T>> arbitrary() {
141     // TODO fapply
142     return gen::map(
143         gen::pair(
144             gen::arbitrary<T>(),
145             gen::scale(0.25, gen::lazy(&gen::arbitrary<Seq<Shrinkable<T>>>))),
146         [](std::pair<T, Seq<Shrinkable<T>>> &&p) {
147           return shrinkable::just(std::move(p.first), std::move(p.second));
148         });
149   }
150 };
151 
152 template <typename T, typename... Ts>
153 struct Arbitrary<detail::Variant<T, Ts...>> {
154   static Gen<detail::Variant<T, Ts...>> arbitrary() {
155     return gen::oneOf(
156         gen::cast<detail::Variant<T, Ts...>>(gen::arbitrary<T>()),
157         gen::cast<detail::Variant<T, Ts...>>(gen::arbitrary<Ts>())...);
158   }
159 };
160 
161 } // namespace rc
162