1 module dud.semver.versionrangetest;
2 
3 @safe pure private:
4 import std.format : format;
5 import std.typecons : Nullable;
6 import dud.semver.semver;
7 import dud.semver.parse;
8 import dud.semver.versionrange;
9 
10 unittest {
11 	void test(const SemVer lowA, const Inclusive lowAIn, const SemVer highA,
12 			const Inclusive highAIn, const SemVer lowB, const Inclusive lowBIn,
13 			const SemVer highB, const Inclusive highBIn,
14 			const SetRelation br)
15 	{
16 		auto v1 = VersionRange(lowA, lowAIn, highA, highAIn);
17 		auto v2 = VersionRange(lowB, lowBIn, highB, highBIn);
18 
19 		auto b = relation(v1, v2);
20 		assert(b == br, format(
21 			"\nexp: %s\ngot: %s\na: %s\nb: %s", br, b, v1, v2));
22 	}
23 
24 	const i = Inclusive.yes;
25 	const o = Inclusive.no;
26 
27 	auto a = parseSemVer("0.0.0");
28 	auto b = parseSemVer("1.0.0");
29 	auto c = parseSemVer("2.0.0");
30 	auto d = parseSemVer("3.0.0");
31 	auto e = parseSemVer("4.0.0");
32 
33 	// a: [ . ] . . . . . . . .
34 	// b: . . . [ . . . ] . . .
35 
36 	test(a, i, b, i, c, i, e, i, SetRelation.disjoint);
37 
38 	// a: [ . ) . . . . . . . .
39 	// b: . . [ . . . . ] . . .
40 	test(a, i, b, o, b, i, e, i, SetRelation.disjoint);
41 	// a: . . . . . . . . [ . ]
42 	// b: . . . [ . . . ] . . .
43 
44 	test(e, i, e, i, b, i, c, i, SetRelation.disjoint);
45 
46 	// a: . . . . . . . . [ . ]
47 	// b: . . . [ . . . . ) . .
48 	test(d, i, e, i, b, i, d, o, SetRelation.disjoint);
49 	// a: . . . ( . . . . ) . .
50 	// b: . . . [ . . . . ] . .
51 	test(b, o, e, o, b, i, e, i, SetRelation.subset);
52 
53 	// a: . . . [ . . . . ) . .
54 	// b: . . . [ . . . . ] . .
55 	test(b, i, e, o, b, i, e, i, SetRelation.subset);
56 
57 	// a: . . . [ . . . . ] . .
58 	// b: . . . [ . . . . ] . .
59 	test(b, i, e, i, b, i, e, i, SetRelation.subset);
60 
61 	// a: . . . ( . . . . ] . .
62 	// b: . . . [ . . . . ] . .
63 	test(b, o, e, i, b, i, e, i, SetRelation.subset);
64 
65 	// a: . . . ( . . . . ] . .
66 	// b: . . . ( . . . . ] . .
67 	test(b, o, e, i, b, o, e, i, SetRelation.subset);
68 
69 	// a: . . . ( . . . . ) . .
70 	// b: . . . ( . . . . ) . .
71 	test(b, o, e, o, b, o, e, o, SetRelation.subset);
72 
73 	// a: . . . . | . . . | . .
74 	// b: . . . | . . . . | . .
75 	test(c, o, e, o, b, o, e, o, SetRelation.subset);
76 
77 	// a: . . . . | . . | . . .
78 	// b: . . . | . . . . | . .
79 	test(c, o, d, o, b, o, e, o, SetRelation.subset);
80 
81 	// a: . . . | . . . | . . .
82 	// b: . . . | . . . . | . .
83 	test(b, o, d, o, b, o, e, o, SetRelation.subset);
84 	test(b, o, d, o, b, i, e, i, SetRelation.subset);
85 
86 	// a: [ . ] . . . . . . . .
87 	// b: . . [ . . . . ] . . .
88 	test(a, i, b, i, b, i, e, i, SetRelation.overlapping);
89 
90 	// a: . . . . . . . . [ . ]
91 	// b: . . . [ . . . . ] . .
92 	test(d, i, e, i, b, i, d, i, SetRelation.overlapping);
93 
94 	// a: . . . . . . . | . . |
95 	// b: . . . [ . . . . ] . .
96 	test(c, i, e, i, b, i, d, i, SetRelation.overlapping);
97 
98 	// a: . | . . . . . | . . .
99 	// b: . . . [ . . . . ] . .
100 	test(a, i, c, i, b, i, d, i, SetRelation.overlapping);
101 
102 	// a: . | . . . . . . | . .
103 	// b: . . . | . . . . | . .
104 	test(a, i, d, i, b, i, d, i, SetRelation.overlapping);
105 
106 	// a: . . . | . . . . . | .
107 	// b: . . . | . . . . | . .
108 	test(b, i, e, i, b, i, d, i, SetRelation.overlapping);
109 
110 	// a: . . [ . . . . . . ] .
111 	// b: . . . [ . . . . ] . .
112 	test(a, i, e, i, b, i, d, i, SetRelation.overlapping);
113 
114 	// a: . . . [ . . . . ] . .
115 	// b: . . . [ . . . . ) . .
116 	test(b, i, c, i, b, i, c, o, SetRelation.overlapping);
117 
118 	// a: . . . [ . . . . ] . .
119 	// b: . . . ( . . . . ] . .
120 	test(b, i, c, i, b, o, c, i, SetRelation.overlapping);
121 
122 	// a: . . . [ . . . . ] . .
123 	// b: . . . ( . . . . ) . .
124 	test(b, i, c, i, b, o, c, i, SetRelation.overlapping);
125 
126 	// a: . . . ( . . . . ] . .
127 	// b: . . . [ . . . . ) . .
128 	test(b, i, c, o, b, o, c, i, SetRelation.overlapping);
129 
130 	// a: . . . [ . . . . ] . .
131 	// b: . . . ( . . . . ) . .
132 	test(b, i, c, i, b, o, c, o, SetRelation.overlapping);
133 
134 	// a: . . . [ . . . . ) . .
135 	// b: . . . ( . . . . ) . .
136 	test(b, i, c, o, b, o, c, o, SetRelation.overlapping);
137 
138 	// a: . . . [ . . . . ] . .
139 	// b: . . . ( . . . ] . . .
140 	test(b, i, d, i, b, o, c, i, SetRelation.overlapping);
141 
142 	// a: . . . [ . . . . ) . .
143 	// b: . . . . ( . . . ] . .
144 	test(b, i, d, o, c, i, d, i, SetRelation.overlapping);
145 
146 	// a: . . . ( . . . . ] . .
147 	// b: . . . [ . . . . ) . .
148 	test(b, o, d, i, b, i, d, o, SetRelation.overlapping);
149 }
150 
151 unittest {
152 	auto a = parseSemVer("0.0.0");
153 	auto b = parseSemVer("1.0.0");
154 	auto c = parseSemVer("2.0.0");
155 
156 	auto v1 = VersionRange(b, Inclusive.yes, c, Inclusive.no);
157 	auto v2 = VersionRange(a, Inclusive.yes, b, Inclusive.no);
158 
159 	SetRelation sr = relation(v1, v2);
160 	assert(sr == SetRelation.disjoint, format("%s", sr));
161 }
162 
163 unittest {
164 	Nullable!VersionRange vr1 = parseVersionRange(">=1.0.0");
165 	assert(!vr1.isNull());
166 	assert(vr1.get() != VersionRange.init);
167 }
168 
169 unittest {
170 	SemVer[] sv =
171 		[ parseSemVer("1.0.0"), parseSemVer("2.0.0"), parseSemVer("3.0.0")
172 		, parseSemVer("4.0.0"), parseSemVer("5.0.0")
173 		];
174 
175 	Inclusive[] inclusive  = [Inclusive.yes, Inclusive.no];
176 
177 	VersionRange[] vers;
178 	foreach(idx, low; sv[0 .. $ - 1]) {
179 		foreach(lowIn; inclusive) {
180 			foreach(high; sv[idx + 1 .. $]) {
181 				foreach(highIn; inclusive) {
182 					VersionRange tmp;
183 					tmp.inclusiveLow = lowIn;
184 					tmp.low = low;
185 					tmp.inclusiveHigh = highIn;
186 					tmp.high = high;
187 					vers ~= tmp;
188 				}
189 			}
190 		}
191 	}
192 
193 	//debug writefln("%(%s\n%)", vers);
194 	foreach(adx, verA; vers) {
195 		foreach(bdx, verB; vers) {
196 			assert(!verA.isBranch());
197 			assert(!verB.isBranch());
198 			auto rel = relation(verA, verB);
199 			//writefln("a: %s, b: %s, rel %s", verA, verB, rel);
200 			auto reporter = () {
201 				return format("\na: %s, b: %s, rel %s", verA, verB, rel);
202 			};
203 			if(adx == bdx) {
204 				assert(rel == SetRelation.subset, reporter());
205 			} else if(verA.high < verB.low) {
206 				assert(rel == SetRelation.disjoint, reporter());
207 			} else if(verA.low > verB.high) {
208 				assert(rel == SetRelation.disjoint, reporter());
209 			} else if(verA.low < verB.low && verA.high > verB.high) {
210 				assert(rel == SetRelation.overlapping, reporter());
211 			} else if(verA.low > verB.low && verA.high < verB.high) {
212 				assert(rel == SetRelation.subset, reporter());
213 			} else {
214 				assert((rel == SetRelation.overlapping)
215 						|| (rel == SetRelation.subset)
216 						|| (rel == SetRelation.disjoint), reporter());
217 			}
218 		}
219 	}
220 }
221 
222 unittest {
223 	SemVer a = parseSemVer("1.0.0");
224 	SemVer b = parseSemVer("2.0.0");
225 	SemVer c = parseSemVer("3.0.0");
226 
227 	auto v1 = VersionRange(a, Inclusive.no, b, Inclusive.yes);
228 	auto v2 = VersionRange(b, Inclusive.yes, c, Inclusive.yes);
229 	assert(!v1.isBranch());
230 	assert(!v2.isBranch());
231 
232 	auto rel = relation(v1, v2);
233 	assert(rel == SetRelation.overlapping, format("%s", rel));
234 }
235 
236 unittest {
237 	SemVer a = parseSemVer("1.0.0");
238 	SemVer b = parseSemVer("2.0.0");
239 	SemVer c = parseSemVer("3.0.0");
240 	SemVer d = parseSemVer("99999.0.0");
241 
242 	auto v1 = VersionRange(a, Inclusive.no, b, Inclusive.no);
243 	assert(!v1.isBranch());
244 	auto v2 = VersionRange(b, Inclusive.no, c, Inclusive.yes);
245 	assert(!v2.isBranch());
246 	auto v3 = VersionRange(b, Inclusive.yes, c, Inclusive.yes);
247 	assert(!v3.isBranch());
248 	auto v4 = VersionRange(a, Inclusive.no, b, Inclusive.yes);
249 	assert(!v4.isBranch());
250 	auto v5 = VersionRange(b, Inclusive.yes, c, Inclusive.yes);
251 	assert(!v5.isBranch());
252 	auto v6 = VersionRange(c, Inclusive.no, d, Inclusive.yes);
253 	assert(!v6.isBranch());
254 
255 	auto rel = relation(v1, v2);
256 	assert(rel == SetRelation.disjoint, format("%s", rel));
257 
258 	rel = relation(v1, v3);
259 	assert(rel == SetRelation.disjoint, format("%s", rel));
260 
261 	rel = relation(v3, v4);
262 	assert(rel == SetRelation.overlapping, format("%s", rel));
263 
264 	rel = relation(v5, v6);
265 	assert(rel == SetRelation.disjoint, format("%s", rel));
266 }
267 
268 unittest {
269 	const VersionRange vr1 = VersionRange("master");
270 	Nullable!VersionRange vr2n = parseVersionRange(">=1.0.0");
271 	assert(!vr2n.isNull());
272 	const VersionRange vr2 = vr2n.get();
273 	assert(vr1 < vr2);
274 	assert(vr2 > vr1);
275 	assert(vr1 <= vr1);
276 
277 	const VersionRange vr3 = vr1.dup();
278 	assert(vr3 == vr1);
279 }
280 
281 unittest {
282 	const SemVer sv1 = SemVer(1,0,0);
283 	const SemVer sv2 = SemVer(2,0,0);
284 	const VersionRange vr1 = VersionRange(sv1, Inclusive.yes, sv2,
285 			Inclusive.no);
286 	const VersionRange vr2 = VersionRange(sv1, Inclusive.no, sv2,
287 			Inclusive.no);
288 
289 	assert(vr1 > vr2);
290 	assert(vr2 < vr1);
291 	assert(vr1 <= vr1);
292 }