UNPKG

betwixt

Version:

String rank for re-orderable lists

273 lines (267 loc) 10.8 kB
(function() { var Betwixt, path; path = require("path"); Betwixt = require(path.join("..", "betwixt")); require("jasmine-given"); describe("Betwixt", function() { var zero; Given(function() { return this.Betwixt = Betwixt; }); Given(function() { return this.zero = "\u0000"; }); zero = "\u0000"; describe("trim", function() { return it("should trim trailing zeros", function() { expect(Betwixt.trim("\uaaaa\u0000")).toEqual("\uaaaa"); return expect(Betwixt.trim("\u0000")).toEqual(""); }); }); describe("validated", function() { var nonempty; nonempty = "\uaaaa\u0000"; it("should return the same value as trim for nonempty strings", function() { return expect(Betwixt.validated(nonempty)).toEqual(Betwixt.trim(nonempty)); }); return it("should throw an error if its parameter is zero/empty", function() { expect(function() { return Betwixt.validated(zero); }).toThrowError(Error); return expect(function() { return Betwixt.validated(""); }).toThrowError(Error); }); }); describe("midpoint", function() { Given(function() { return this.m = this.Betwixt.midpoint(); }); return Then(function() { return this.m === "\u8000"; }); }); describe("toHex", function() { return Then(function() { return this.Betwixt.toHex("\uBEAD\ucafe") === "beadcafe"; }); }); describe("before and after", function() { Given(function() { return this.start = "\u1234"; }); Given(function() { return this.extra = "\ufade\ucafe"; }); Given(function() { return this.ffff = "\uffff"; }); describe("They trim their arguments", function() { Then(function() { return this.Betwixt.before(this.start + this.zero) === this.Betwixt.before(this.start); }); Then(function() { return this.Betwixt.before(this.ffff + this.zero) === this.Betwixt.before(this.ffff); }); Then(function() { return this.Betwixt.after(this.ffff + this.zero) === this.Betwixt.after(this.ffff); }); return Then(function() { return this.Betwixt.after(this.zero) === this.Betwixt.after(""); }); }); describe("before", function() { Given(function() { return this.decrement = "\u1233"; }); it("should throw an error if its parameter is zero/empty", function() { expect(function() { return Betwixt.before(zero); }).toThrowError(Error); return expect(function() { return Betwixt.before(""); }).toThrowError(Error); }); describe("before treats the first non-zero character code as an integer and decrements it", function() { Then(function() { return this.Betwixt.before(this.start) === this.decrement; }); return Then(function() { return this.Betwixt.before(this.zero + this.start) === this.zero + this.decrement; }); }); describe("before throws away anything after the decremented character", function() { Then(function() { return this.Betwixt.before(this.start + this.extra) === this.decrement; }); return Then(function() { return this.Betwixt.before(this.zero + this.start + this.extra) === this.zero + this.decrement; }); }); return describe("if the decrement of the character is @zero, then before appends @Betwixt.midpoint() to the string", function() { Then(function() { return this.Betwixt.before("\u0001") === this.zero + this.Betwixt.midpoint(); }); return Then(function() { return this.Betwixt.before(this.zero + "\u0001") === this.zero + this.zero + this.Betwixt.midpoint(); }); }); }); return describe("after", function() { Given(function() { return this.increment = "\u1235"; }); describe("before treats the first non-0xffff character code as an integer and decrements it", function() { Then(function() { return this.Betwixt.after(this.start) === this.increment; }); return Then(function() { return this.Betwixt.after(this.ffff + this.start) === this.ffff + this.increment; }); }); describe("after throws away anything after the incremented character", function() { Then(function() { return this.Betwixt.after(this.start + this.extra) === this.increment; }); return Then(function() { return this.Betwixt.after(this.ffff + this.start + this.extra) === this.ffff + this.increment; }); }); return describe("When the entire string consists of 0xffff characters, after appends a 0x8000 character to the string", function() { return Then(function() { return this.Betwixt.after(this.ffff + this.ffff) === this.ffff + this.ffff + "\u8000"; }); }); }); }); return describe("between()", function() { Given(function() { return this.a = "\u2001"; }); Given(function() { return this.b = "\u2002"; }); Given(function() { return this.c = "\u2003"; }); describe("between trims its arguments", function() { return Then(function() { return this.Betwixt.between(this.zero, this.zero + this.zero) === ""; }); }); describe("Betwixt.between(x,x) returns x", function() { return Then(function() { return this.Betwixt.between(this.a, this.a) === this.a; }); }); describe("when possible, the fractions are averaged", function() { Then(function() { return this.Betwixt.between(this.a, this.c) === this.b; }); return Then(function() { var ref; return (this.a < (ref = this.Betwixt.between(this.a, this.c)) && ref < this.c); }); }); describe("the order of operands doesn't matter", function() { Then(function() { return this.Betwixt.between(this.b, this.a) === this.Betwixt.between(this.a, this.b); }); return Then(function() { return this.Betwixt.between(this.c, this.a) === this.Betwixt.between(this.a, this.c); }); }); describe("slightly less easy parts", function() { Given(function() { return this.aa = this.a + "\u3333"; }); Given(function() { return this.cc = this.c + "\uffff"; }); describe("If the two characters that first differ can be averaged, anything after them is ignored", function() { return Then(function() { return this.Betwixt.between(this.aa, this.cc) === this.b; }); }); return describe("Strings with leading identical characters do the work after the leading characters", function() { Given(function() { return this.prefix = "\uaaaa\ubbbb\ucccc"; }); return Then(function() { return this.Betwixt.between(this.prefix + this.aa, this.prefix + this.cc) === this.prefix + this.Betwixt.between(this.aa, this.cc); }); }); }); describe("When the strings are the same length and their last characters differ only by one, the result is the prefix of the lesser string, extended by Betwixt.midpoint()", function() { Then(function() { return this.Betwixt.between(this.a, this.b) === "\u2001\u8000"; }); return Then(function() { var ref; return (this.a < (ref = this.Betwixt.between(this.a, this.b)) && ref < this.b); }); }); describe("When the first differing characters differ only by one, and the greater string t has more characters, the result is the prefix of t up to and including the first differing character", function() { Given(function() { return this.lo = "\uaaaa\u1234"; }); Given(function() { return this.hi = "\uaaaa\u1235\ubbb0"; }); return Then(function() { return this.Betwixt.between(this.hi, this.lo) === "\uaaaa\u1235"; }); }); describe("When the lesser string s has more characters than the greater, consider the first differing character c, and the next character d. The between method returns the prefix of s up to and including c, concatenated with a character midway between d and 2**16.", function() { Given(function() { return this.lo = "\uaaaa\u1234\ubbbb\u9999"; }); Given(function() { return this.hi = "\uaaaa\u1235"; }); return Then(function() { return this.Betwixt.between(this.lo, this.hi) === "\uaaaa\u1234\udddd"; }); }); describe("But if character d is 0xffff (2**16-1), then we can't find a character between it and 2**16. So we need to extend our prefix to include c and the longest sequence of 0xffff characters immediately following c. Then d is the character after all of those.", function() { Given(function() { return this.lo = "\uaaaa\u1234\uffff\uffff\ubbbb\u9999"; }); Given(function() { return this.hi = "\uaaaa\u1235"; }); return Then(function() { return this.Betwixt.between(this.lo, this.hi) === "\uaaaa\u1234\uffff\uffff\udddd"; }); }); describe("Furthermore, if *every* character after c is 0xffff, then we append 0x8000 to s itself.", function() { Given(function() { return this.lo = "\uaaaa\u1234\uffff\uffff"; }); Given(function() { return this.hi = "\uaaaa\u1235"; }); return Then(function() { return this.Betwixt.between(this.hi, this.lo) === "\uaaaa\u1234\uffff\uffff\u8000"; }); }); return describe("If s is a prefix of t, then between acts as if s were extended by a ZERO character.", function() { Given(function() { return this.lo = "\uaaaa"; }); Given(function() { return this.hi = "\uaaaa\u8000"; }); Given(function() { return this.just_higher = "\uaaaa\u0001"; }); Then(function() { return this.Betwixt.between(this.lo, this.hi) === "\uaaaa\u4000"; }); return Then(function() { return this.Betwixt.between(this.lo, this.just_higher) === "\uaaaa\u0000\u8000"; }); }); }); }); }).call(this);