1 module dud.resolve.versionconfigurationtoolchaintest;
2 
3 @safe pure:
4 
5 import dud.resolve.versionconfigurationtoolchain;
6 import dud.resolve.conf;
7 import dud.resolve.confs;
8 import dud.resolve.positive;
9 import dud.semver.semver;
10 import dud.semver.setoperation;
11 import dud.semver.parse;
12 import dud.semver.versionunion;
13 import dud.semver.versionrange;
14 import dud.resolve.toolchain;
15 
16 import std.format : format;
17 import std.stdio;
18 
19 private:
20 
21 immutable SemVer s10 = SemVer(1,0,0);
22 immutable SemVer s15 = SemVer(1,5,0);
23 immutable SemVer s20 = SemVer(2,0,0);
24 immutable SemVer s25 = SemVer(2,5,0);
25 immutable SemVer s30 = SemVer(3,0,0);
26 
27 immutable allS = [s10, s15, s20, s25, s30];
28 
29 immutable Conf c1 = Conf("", IsPositive.yes);
30 immutable Conf c2 = Conf("", IsPositive.no);
31 immutable Conf c3 = Conf("foo", IsPositive.yes);
32 immutable Conf c4 = Conf("foo", IsPositive.no);
33 immutable Conf c5 = Conf("bar", IsPositive.yes);
34 immutable Conf c6 = Conf("bar", IsPositive.no);
35 
36 immutable allC = [c1, c2, c3, c4, c5, c6];
37 
38 VerConGen verConGen(uint seed) {
39 	import std.random : Random;
40 
41 	VerConGen ret;
42 	ret.rnd = Random(seed);
43 	ret.popFront();
44 	return ret;
45 }
46 
47 struct VerConGen {
48 @safe pure:
49 	import std.random : Random, uniform, randomCover;
50 	import std.algorithm.iteration : map;
51 	import std.range : take, iota;
52 	import std.array : array;
53 	Random rnd;
54 
55 	bool empty;
56 	VersionConfigurationToolchain front;
57 
58 	VersionRange newVersionRange() {
59 		const sl = uniform(0, allS.length - 1, this.rnd);
60 		const sh = uniform(sl, allS.length, this.rnd);
61 		return VersionRange(
62 				allS[sl],
63 				uniform(0, 100, this.rnd) < 50 && sl != sh
64 					? Inclusive.no
65 					: Inclusive.yes,
66 				allS[sh],
67 				uniform(0, 100, this.rnd) < 50 && sl != sh
68 					? Inclusive.no
69 					: Inclusive.yes);
70 	}
71 
72 	void popFront() {
73 		const cl = uniform(1, 4, this.rnd);
74 		const vrC = uniform(1, 3, this.rnd);
75 
76 		const vrs = iota(vrC).map!(it => newVersionRange()).array;
77 
78 		this.front = VersionConfigurationToolchain(
79 			vrs.VersionUnion,
80 			allC.randomCover(this.rnd).take(cl).array.Confs);
81 
82 	}
83 }
84 
85 immutable vc1 = VersionConfigurationToolchain(
86 		VersionUnion([VersionRange(s15, Inclusive.yes, s25, Inclusive.yes)]),
87 		Confs([c1, c3]));
88 
89 immutable vc2 = VersionConfigurationToolchain(
90 		VersionUnion([VersionRange(s15, Inclusive.yes, s25, Inclusive.yes)]),
91 		Confs([c3]));
92 
93 immutable vc3 = VersionConfigurationToolchain(
94 		VersionUnion([VersionRange(s15, Inclusive.yes, s25, Inclusive.yes)]),
95 		Confs([c1]));
96 
97 immutable vc4 = VersionConfigurationToolchain(
98 		VersionUnion([VersionRange(s20, Inclusive.yes, s30, Inclusive.yes)]),
99 		Confs([c1, c3]));
100 
101 immutable vc5 = VersionConfigurationToolchain(
102 		VersionUnion([VersionRange(s10, Inclusive.yes, s15, Inclusive.yes)]),
103 		Confs([c1, c3]));
104 
105 immutable vc6 = VersionConfigurationToolchain(
106 		VersionUnion([VersionRange(s25, Inclusive.yes, s30, Inclusive.yes)]),
107 		Confs([c1, c3]));
108 
109 immutable vc7 = VersionConfigurationToolchain(
110 		VersionUnion([VersionRange(s25, Inclusive.yes, s30, Inclusive.yes)]),
111 		Confs([c1, c4]));
112 
113 immutable vc8 = VersionConfigurationToolchain(
114 		VersionUnion([VersionRange(s25, Inclusive.yes, s30, Inclusive.yes)]),
115 		Confs([c3]));
116 
117 immutable vc9 = VersionConfigurationToolchain(
118 		VersionUnion([VersionRange(s25, Inclusive.yes, s30, Inclusive.yes)]),
119 		Confs([c1]));
120 
121 immutable vcA = VersionConfigurationToolchain(
122 		VersionUnion([VersionRange(s25, Inclusive.yes, s30, Inclusive.yes)]),
123 		Confs([c5]));
124 
125 // allowsAll
126 
127 void testAllowsAll(const(VersionConfigurationToolchain) a, const(VersionConfigurationToolchain) b
128 		, const bool exp, int line = __LINE__)
129 {
130 	import core.exception : AssertError;
131 	import std.exception : enforce;
132 
133 	const bool rslt = allowsAll(a, b);
134 	enforce!AssertError(rslt == exp,
135 		format("\na: %s\nb: %s\nexp: %s\nrsl: %s", a, b,
136 			exp,
137 			rslt)
138 		, __FILE__, line);
139 }
140 
141 unittest {
142 	testAllowsAll(vc9, vc8, true);
143 	testAllowsAll(vc9, vc9, true);
144 	testAllowsAll(vc9, vcA, true);
145 }
146 
147 unittest {
148 	testAllowsAll(vc6, vc1, false);
149 	testAllowsAll(vc6, vc2, false);
150 	testAllowsAll(vc6, vc3, false);
151 	testAllowsAll(vc6, vc4, false);
152 	testAllowsAll(vc6, vc5, false);
153 	testAllowsAll(vc6, vc6, true);
154 
155 	testAllowsAll(vc5, vc1, false);
156 	testAllowsAll(vc5, vc2, false);
157 	testAllowsAll(vc5, vc3, false);
158 	testAllowsAll(vc5, vc4, false);
159 	testAllowsAll(vc5, vc5, true);
160 	testAllowsAll(vc5, vc6, false);
161 
162 	testAllowsAll(vc4, vc1, false);
163 	testAllowsAll(vc4, vc2, false);
164 	testAllowsAll(vc4, vc3, false);
165 	testAllowsAll(vc4, vc4, true);
166 	testAllowsAll(vc4, vc5, false);
167 	testAllowsAll(vc4, vc6, true);
168 
169 	testAllowsAll(vc3, vc1, true);
170 	testAllowsAll(vc3, vc2, true);
171 	testAllowsAll(vc3, vc3, true);
172 	testAllowsAll(vc3, vc4, false);
173 	testAllowsAll(vc3, vc5, false);
174 	testAllowsAll(vc3, vc6, false);
175 
176 	testAllowsAll(vc2, vc1, true);
177 	testAllowsAll(vc2, vc2, true);
178 	testAllowsAll(vc2, vc3, true);
179 	testAllowsAll(vc2, vc4, false);
180 	testAllowsAll(vc2, vc5, false);
181 	testAllowsAll(vc2, vc6, false);
182 
183 	testAllowsAll(vc1, vc1, true);
184 	testAllowsAll(vc1, vc2, true);
185 	testAllowsAll(vc1, vc3, true);
186 	testAllowsAll(vc1, vc4, false);
187 	testAllowsAll(vc1, vc5, false);
188 	testAllowsAll(vc1, vc6, false);
189 }
190 
191 // allowsAny
192 
193 unittest {
194 	assert( allowsAny(vc6, vc1));
195 	assert( allowsAny(vc6, vc2));
196 	assert( allowsAny(vc6, vc3));
197 	assert( allowsAny(vc6, vc4));
198 	assert(!allowsAny(vc6, vc5));
199 	assert( allowsAny(vc6, vc6));
200 
201 	assert( allowsAny(vc5, vc1));
202 	assert( allowsAny(vc5, vc2));
203 	assert( allowsAny(vc5, vc3));
204 	assert(!allowsAny(vc5, vc4));
205 	assert( allowsAny(vc5, vc5));
206 	assert(!allowsAny(vc5, vc6));
207 
208 	assert( allowsAny(vc4, vc1));
209 	assert( allowsAny(vc4, vc2));
210 	assert( allowsAny(vc4, vc3));
211 	assert( allowsAny(vc4, vc4));
212 	assert(!allowsAny(vc4, vc5));
213 	assert( allowsAny(vc4, vc6));
214 
215 	assert( allowsAny(vc3, vc1));
216 	assert( allowsAny(vc3, vc2));
217 	assert( allowsAny(vc3, vc3));
218 	assert( allowsAny(vc3, vc4));
219 	assert( allowsAny(vc3, vc5));
220 	assert( allowsAny(vc3, vc6));
221 
222 	assert( allowsAny(vc2, vc1));
223 	assert( allowsAny(vc2, vc2));
224 	assert( allowsAny(vc2, vc3));
225 	assert( allowsAny(vc2, vc4));
226 	assert( allowsAny(vc2, vc5));
227 	assert( allowsAny(vc2, vc6));
228 
229 	assert( allowsAny(vc1, vc1));
230 	assert( allowsAny(vc1, vc2));
231 	assert( allowsAny(vc1, vc3));
232 	assert( allowsAny(vc1, vc4));
233 	assert( allowsAny(vc1, vc5));
234 	assert( allowsAny(vc1, vc6));
235 }
236 
237 unittest {
238 	static import dud.semver.checks;
239 
240 	auto vc1 = VersionConfigurationToolchain(VersionUnion(
241 			[parseVersionRange(">=2.5.0 <=2.5.0").get()]),
242 			Confs([Conf("", IsPositive.yes)]));
243 	auto vc2 = VersionConfigurationToolchain(VersionUnion(
244 			[parseVersionRange(">=2.5.0 <=2.5.0").get()]),
245 			Confs([Conf("", IsPositive.no)]));
246 	assert(!allowsAll(vc1, vc2), format("\nvc1: %s\nvc2: %s", vc1, vc2));
247 	assert(!allowsAny(vc1, vc2), format(
248 			"\nvc1: %s\nvc2: %s\nversionunion %s\nconfs %s", vc1, vc2
249 			, dud.semver.checks.allowsAny(vc1.ver, vc2.ver)
250 			, dud.resolve.confs.allowsAny(vc1.conf, vc2.conf)
251 			));
252 }
253 
254 unittest {
255 	import std.range : take;
256 
257 	static import dud.semver.checks;
258 
259 	auto r1 = verConGen(1337);
260 	auto r2 = verConGen(1338);
261 	foreach(it; take(r1, 500)) {
262 		foreach(jt; take(r2, 500)) {
263 			const al = allowsAll(it, jt);
264 			if(al) {
265 				assert(allowsAny(it, jt), format(
266 						"\nit: %s\njt: %s\n\tpart any all\nversionunion %s %s\nconfs "
267 							~ "%s %s\ntoolchain %s %s"
268 						, it, jt
269 						, dud.semver.checks.allowsAny(it.ver, jt.ver)
270 						, dud.semver.checks.allowsAll(it.ver, jt.ver)
271 						, dud.resolve.confs.allowsAny(it.conf, jt.conf)
272 						, dud.resolve.confs.allowsAll(it.conf, jt.conf)
273 						, dud.resolve.toolchain.allowsAny(it.toolchains
274 							, jt.toolchains)
275 						, dud.resolve.toolchain.allowsAll(it.toolchains
276 							, jt.toolchains)
277 						));
278 			}
279 		}
280 	}
281 }
282 
283 // intersectionOf
284 
285 void testRelation(const(VersionConfigurationToolchain) a, const(VersionConfigurationToolchain) b,
286 		const(SetRelation) exp, int line = __LINE__)
287 {
288 	import std.exception : enforce;
289 	import core.exception : AssertError;
290 	const(SetRelation) rslt = relation(a, b);
291 	enforce!AssertError(rslt == exp,
292 		format("\na: %s\nb: %s\nexp: %s\nrsl: %s", a, b, exp, rslt),
293 		__FILE__, line);
294 
295 }
296 
297 unittest {
298 	auto v1 = VersionConfigurationToolchain(
299 			VersionUnion([VersionRange(s10, Inclusive.yes, s15, Inclusive.yes)])
300 				, Confs([Conf("", IsPositive.yes)])
301 			);
302 	auto v2 = VersionConfigurationToolchain(
303 			VersionUnion([VersionRange(s10, Inclusive.yes, s15, Inclusive.no)])
304 				, Confs([Conf("", IsPositive.yes)])
305 			);
306 	auto v3 = VersionConfigurationToolchain(
307 			VersionUnion([VersionRange(s10, Inclusive.yes, s20, Inclusive.no)])
308 				, Confs([Conf("", IsPositive.yes)])
309 			);
310 	auto v4 = VersionConfigurationToolchain(
311 			VersionUnion([VersionRange(s10, Inclusive.yes, s20, Inclusive.no)])
312 				, Confs([Conf("", IsPositive.yes)])
313 			);
314 
315 	testRelation(v1, v2, SetRelation.overlapping);
316 	testRelation(v1, v3, SetRelation.subset);
317 	testRelation(v2, v4, SetRelation.subset);
318 	testRelation(v1, v4, SetRelation.subset);
319 	testRelation(v4, v2, SetRelation.overlapping);
320 }
321 
322 unittest {
323 	auto v1 = VersionConfigurationToolchain(
324 			VersionUnion([VersionRange(s10, Inclusive.yes, s15, Inclusive.yes)])
325 			, Confs([Conf("conf1", IsPositive.yes)]));
326 	auto v2 = VersionConfigurationToolchain(
327 			VersionUnion([VersionRange(s10, Inclusive.yes, s15, Inclusive.no)])
328 			, Confs([Conf("", IsPositive.yes)]));
329 	auto v3 = VersionConfigurationToolchain(
330 			VersionUnion([VersionRange(s10, Inclusive.yes, s15, Inclusive.yes)])
331 			, Confs([Conf("conf2", IsPositive.yes)]));
332 
333 	testRelation(v1, v1, SetRelation.subset);
334 	testRelation(v1, v2, SetRelation.overlapping);
335 	testRelation(v1, v3, SetRelation.disjoint);
336 
337 	testRelation(v2, v1, SetRelation.subset);
338 	testRelation(v2, v2, SetRelation.subset);
339 	testRelation(v2, v3, SetRelation.subset);
340 
341 	testRelation(v3, v1, SetRelation.disjoint);
342 	testRelation(v3, v2, SetRelation.overlapping);
343 	testRelation(v3, v3, SetRelation.subset);
344 }
345 
346 unittest {
347 	auto v1 = VersionConfigurationToolchain(
348 			VersionUnion([ parseVersionRange(">=1.0.0").get() ])
349 			, Confs([Conf("", IsPositive.yes)])
350 		);
351 
352 	auto v2 = v1.invert();
353 	assert(relation(v1, v2) == SetRelation.disjoint);
354 }
355 
356 unittest {
357 	auto v1 = VersionConfigurationToolchain(
358 			VersionUnion([VersionRange(s10, Inclusive.yes, s30, Inclusive.yes)])
359 			, Confs([Conf("conf1", IsPositive.yes)]));
360 	auto v2 = VersionConfigurationToolchain(
361 			VersionUnion([VersionRange(s15, Inclusive.yes, s20, Inclusive.no)])
362 			, Confs([Conf("", IsPositive.yes)]));
363 
364 	auto v12 = intersectionOf(v1, v2);
365 	debug writeln(v1);
366 	debug writeln(v2);
367 	debug writeln(v12);
368 	assert(v12.conf == Confs([Conf("conf1", IsPositive.yes)])
369 			, format("%s", v12.conf));
370 	testRelation(v1, v12, SetRelation.overlapping);
371 	testRelation(v2, v12, SetRelation.subset);
372 
373 	auto v3 = VersionConfigurationToolchain(
374 			VersionUnion([VersionRange(s25, Inclusive.yes, s30, Inclusive.no)])
375 			, Confs([Conf("conf1", IsPositive.yes)]));
376 	testRelation(v3, v12, SetRelation.disjoint);
377 	testRelation(v12, v3, SetRelation.disjoint);
378 }