diff options
Diffstat (limited to 'appl/spree/lib/testsets.b')
| -rw-r--r-- | appl/spree/lib/testsets.b | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/appl/spree/lib/testsets.b b/appl/spree/lib/testsets.b new file mode 100644 index 00000000..2556838f --- /dev/null +++ b/appl/spree/lib/testsets.b @@ -0,0 +1,152 @@ +implement Testsets; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "rand.m"; +include "sets.m"; # "sets.m" or "sets32.m" + sets: Sets; + Set, set, A, B: import sets; + +BPW: con 32; +SHIFT: con 5; +MASK: con 31; + +Testsets: module { + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +∅: Set; + +Testbig: con 1; + +init(ctxt: ref Draw->Context, argv: list of string) +{ + sys = load Sys Sys->PATH; + sets = load Sets Sets->PATH; + if (sets == nil) { + sys->print("cannot load %s: %r\n", Sets->PATH); + exit; + } + rand := load Rand Rand->PATH; + sets->init(); + + ∅ = set(); + s := set().addlist(1::2::3::4::nil); + addit(s); + sys->print("s %s\n", s.str()); + r := s.invert(); + sys->print("r %s\n", r.str()); + r = r.del(20); + addit(r); + sys->print("r del20: %s\n", r.str()); + z := r.X(~A&~B, s); + addit(z); + sys->print("z: %s\n", z.str()); + + x := set(); + for (i := 0; i < 31; i++) + if (rand->rand(2)) + x = x.add(i); + addit(x); + for(i = 0; i < 31; i++) + addit(set().add(i)); + if (Testbig) { + r = r.del(100); + addit(r); + sys->print("rz: %s\n", r.str()); + r = r.add(100); + addit(r); + sys->print("rz2: %s\n", r.str()); + x = set(); + for (i = 0; i < 200; i++) + x = x.add(rand->rand(300)); + addit(x); + for(i = 31; i < 70; i++) + addit(set().add(i)); + } + sys->print("empty: %s\n", set().str()); + addit(set()); + sys->print("full: %s\n", set().invert().str()); + test(); + sys->print("done tests\n"); +} + +ds(d: array of byte): string +{ + s := ""; + for(i := len d - 1; i >= 0; i--) + s += sys->sprint("%.2x", int d[i]); + return s; +} + +testsets: list of Set; +addit(s: Set) +{ + testsets = s :: testsets; +} + +test() +{ + for (t := testsets; t != nil; t = tl t) + testsets = (hd t).invert() :: testsets; + + for (t = testsets; t != nil; t = tl t) + testa(hd t); + for (t = testsets; t != nil; t = tl t) { + a := hd t; + for (s := testsets; s != nil; s = tl s) { + b := hd s; + testab(a, b); + } + } +} + +testab(a, b: Set) +{ + { + check(!a.eq(b) == !b.eq(a), "equality"); + if (superset(a, b) && !a.eq(b)) + check(!superset(b, a), "superset"); + } exception { + "test failed" => + sys->print("%s, %s [%s, %s]\n", a.str(), b.str(), a.debugstr(), b.debugstr()); + } +} + +testa(a: Set) +{ + { + check(sets->str2set(a.str()).eq(a), "string conversion"); + check(a.eq(a), "self equality"); + check(a.eq(a.invert().invert()), "double inversion"); + check(a.X(A&~B, a).eq(∅), "self not intersect"); + check(a.limit() == a.invert().limit(), "invert limit"); + check(a.X(A&~B, set().invert()).limit() == 0, "zero limit"); + check(sets->bytes2set(a.bytes(0)).eq(a), "bytes conversion"); + check(sets->bytes2set(a.bytes(3)).eq(a), "bytes conversion(2)"); + + if (a.limit() > 0) { + if (a.msb()) + check(!a.holds(a.limit() - 1), "hold limit 1"); + else + check(a.holds(a.limit() - 1), "hold limit 2"); + } + } exception { + "test failed" => + sys->print("%s [%s]\n", a.str(), a.debugstr()); + } +} + +check(ok: int, s: string) +{ + if (!ok) { + sys->print("test failed: %s; ", s); + raise "test failed"; + } +} + +# return true if a is a superset of b +superset(a, b: Set): int +{ + return a.X(~A&B, b).eq(∅); +} |
