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 }