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 }