{"name":"base-test","version":"master","files":{"assocListTest.mo":{"content":"import AssocList \"mo:base/AssocList\";\nimport List \"mo:base/List\";\nimport Nat \"mo:base/Nat\";\nimport Debug \"mo:base/Debug\";\n\nimport Suite \"mo:matchers/Suite\";\nimport T \"mo:matchers/Testable\";\nimport M \"mo:matchers/Matchers\";\n\ntype AssocList = AssocList.AssocList<Nat, Nat>;\n\n// Utility functions for testing\nfunc assocListTest(array : [(Nat, Nat)]) : M.Matcher<AssocList> {\n let map = List.fromArray(array);\n let testableItem : T.TestableItem<AssocList> = {\n display = func l { debug_show l };\n equals = func(l1, l2) {\n List.equal<(Nat, Nat)>(l1, l2, func(p1, p2) = p1.0 == p2.0 and p1.1 == p2.1)\n };\n item = map\n };\n\n M.equals<AssocList>(testableItem)\n};\nfunc natOptAdd(v1 : ?Nat, v2 : ?Nat) : Nat {\n switch (v1, v2) {\n case (?v1, ?v2) v1 + v2;\n case (?v1, null) v1;\n case (null, ?v2) v2;\n case (null, null) Debug.trap \"Unreachable in assocListTest\"\n }\n};\n\n// Sample association lists for testing\nlet map1 = List.fromArray([(0, 10), (2, 12), (4, 14)]);\nlet map2 = List.fromArray([(1, 11), (2, 12)]);\nlet map3 = List.fromArray([(1, 11), (3, 13), (5, 15)]);\n\nlet suite = Suite.suite(\n \"AssocList\",\n [\n Suite.test(\n \"find\",\n AssocList.find(map1, 0, Nat.equal),\n M.equals(T.optional(T.natTestable, ?10 : ?Nat))\n ),\n Suite.test(\n \"find empty\",\n AssocList.find(List.nil(), 0, Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"replace\",\n AssocList.replace(map1, 4, Nat.equal, ?24).0,\n assocListTest([(0, 10), (2, 12), (4, 24)])\n ),\n Suite.test(\n \"replace empty\",\n AssocList.replace(List.nil(), 4, Nat.equal, ?24).0,\n assocListTest([(4, 24)])\n ),\n Suite.test(\n \"replace new entry\",\n AssocList.replace(map1, 1, Nat.equal, ?11).0,\n assocListTest([(0, 10), (2, 12), (4, 14), (1, 11)])\n ),\n Suite.test(\n \"diff no overlap\",\n AssocList.diff(map1, map3, Nat.equal),\n assocListTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"diff empty first\",\n AssocList.diff(List.nil(), map3, Nat.equal),\n assocListTest([])\n ),\n Suite.test(\n \"diff empty second\",\n AssocList.diff(map1, List.nil(), Nat.equal),\n assocListTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"diff both empty\",\n AssocList.diff(List.nil(), List.nil(), Nat.equal),\n assocListTest([])\n ),\n Suite.test(\n \"mapAppend\",\n AssocList.mapAppend<Nat, Nat, Nat, Nat>(\n map1,\n map2,\n natOptAdd\n ),\n assocListTest([(0, 10), (2, 12), (4, 14), (1, 11), (2, 12)])\n ),\n Suite.test(\n \"mapAppend no overlap\",\n AssocList.mapAppend<Nat, Nat, Nat, Nat>(\n map1,\n map3,\n natOptAdd\n ),\n assocListTest([(0, 10), (2, 12), (4, 14), (1, 11), (3, 13), (5, 15)])\n ),\n Suite.test(\n \"mapAppend first empty\",\n AssocList.mapAppend<Nat, Nat, Nat, Nat>(\n List.nil(),\n map3,\n natOptAdd\n ),\n assocListTest([(1, 11), (3, 13), (5, 15)])\n ),\n Suite.test(\n \"mapAppend second empty\",\n AssocList.mapAppend<Nat, Nat, Nat, Nat>(\n map3,\n List.nil(),\n natOptAdd\n ),\n assocListTest([(1, 11), (3, 13), (5, 15)])\n ),\n Suite.test(\n \"mapAppend both empty\",\n AssocList.mapAppend<Nat, Nat, Nat, Nat>(\n List.nil(),\n List.nil(),\n natOptAdd\n ),\n assocListTest([])\n ),\n // FIXME disjDisjoint is equivalent to mapAppend\n Suite.test(\n \"disj\",\n AssocList.disj<Nat, Nat, Nat, Nat>(\n map1,\n map2,\n Nat.equal,\n natOptAdd\n ),\n assocListTest([(0, 10), (4, 14), (1, 11), (2, 24)])\n ),\n Suite.test(\n \"disj no overlap\",\n AssocList.disj<Nat, Nat, Nat, Nat>(\n map1,\n map3,\n Nat.equal,\n natOptAdd\n ),\n assocListTest([(0, 10), (2, 12), (4, 14), (1, 11), (3, 13), (5, 15)])\n ),\n Suite.test(\n \"disj first empty\",\n AssocList.disj<Nat, Nat, Nat, Nat>(\n List.nil(),\n map3,\n Nat.equal,\n natOptAdd\n ),\n assocListTest([(1, 11), (3, 13), (5, 15)])\n ),\n Suite.test(\n \"disj second empty\",\n AssocList.disj<Nat, Nat, Nat, Nat>(\n map1,\n List.nil(),\n Nat.equal,\n natOptAdd\n ),\n assocListTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"disj both empty\",\n AssocList.disj<Nat, Nat, Nat, Nat>(\n List.nil(),\n List.nil(),\n Nat.equal,\n natOptAdd\n ),\n assocListTest([])\n ),\n Suite.test(\n \"join\",\n AssocList.join<Nat, Nat, Nat, Nat>(\n map1,\n map2,\n Nat.equal,\n Nat.add\n ),\n assocListTest([(2, 24)])\n ),\n Suite.test(\n \"join no overlap\",\n AssocList.join<Nat, Nat, Nat, Nat>(\n map1,\n map3,\n Nat.equal,\n Nat.add\n ),\n assocListTest([])\n ),\n Suite.test(\n \"join first empty\",\n AssocList.join<Nat, Nat, Nat, Nat>(\n List.nil(),\n map3,\n Nat.equal,\n Nat.add\n ),\n assocListTest([])\n ),\n Suite.test(\n \"join second empty\",\n AssocList.join<Nat, Nat, Nat, Nat>(\n map1,\n List.nil(),\n Nat.equal,\n Nat.add\n ),\n assocListTest([])\n ),\n Suite.test(\n \"join both empty\",\n AssocList.join<Nat, Nat, Nat, Nat>(\n List.nil(),\n List.nil(),\n Nat.equal,\n Nat.add\n ),\n assocListTest([])\n ),\n Suite.test(\n \"fold\",\n AssocList.fold<Nat, Nat, Nat>(\n map1,\n 0,\n func(k, v, acc) = k * v + acc\n ),\n M.equals(T.nat((0 * 10) + (2 * 12) + (4 * 14)))\n ),\n Suite.test(\n \"fold empty\",\n AssocList.fold<Nat, Nat, Nat>(\n List.nil(),\n 0,\n func(k, v, acc) = k * v + acc\n ),\n M.equals(T.nat(0))\n )\n ]\n);\n\n// FIXME formatter enforcing 4 space indentation\nSuite.run(suite)\n"},"charTest.mo":{"content":"import Debug \"mo:base/Debug\";\nimport Char \"mo:base/Char\";\nimport Prim \"mo:⛔\";\n\n/*\n//\n// Char.toUpper\n//\n\nassert(Char.toUpper('ö') == 'Ö');\nassert(Char.toUpper('σ') == 'Σ');\nassert(Char.toUpper('💩') == '💩');\n\n//\n// Char.toLower\n//\n\nassert(Char.toLower('Ö') == 'ö');\nassert(Char.toLower('Σ') == 'σ');\nassert(Char.toLower('💩') == '💩');\n*/\n\n//\n// Char.isWhitespace\n//\n\nassert (Char.isWhitespace(' '));\n\nassert (not Char.isWhitespace('x'));\n\n// 12288 (U+3000) = ideographic space\nassert (Char.isWhitespace(Prim.nat32ToChar(12288)));\n\nassert (Char.isWhitespace('\\t'));\n\n// Vertical tab ('\\v')\nassert (Char.isWhitespace(Prim.nat32ToChar(0x0B)));\n\n// Form feed ('\\f')\nassert (Char.isWhitespace(Prim.nat32ToChar(0x0C)));\n\nassert (Char.isWhitespace('\\r'));\n\n//\n// Char.isLowercase\n//\n\nassert (Char.isLowercase('x'));\nassert (not Char.isLowercase('X'));\n\n//\n// Char.isUppercase\n//\n\nassert (Char.isUppercase('X'));\nassert (not Char.isUppercase('x'));\n\n//\n// Char.isAlphabetic\n//\n\nassert (Char.isAlphabetic('a'));\nassert (Char.isAlphabetic('京'));\nassert (not Char.isAlphabetic('㋡'))\n"},"dequeTest.mo":{"content":"import Deque \"mo:base/Deque\";\nimport Iter \"mo:base/Iter\";\nimport O \"mo:base/Option\";\nimport D \"mo:base/Debug\";\n\n// test for Queue\ndo {\n var l = Deque.empty<Nat>();\n for (i in Iter.range(0, 100)) {\n l := Deque.pushBack(l, i)\n };\n for (i in Iter.range(0, 100)) {\n let x = Deque.peekFront(l);\n switch (Deque.popFront(l)) {\n case (?(y, l2)) {\n l := l2;\n switch x {\n case null assert false;\n case (?x) assert (x == y)\n }\n };\n case null { assert false }\n };\n assert (O.unwrap(x) == i)\n };\n O.assertNull(Deque.peekFront<Nat>(l))\n};\n\n// test for Deque\ndo {\n var l = Deque.empty<Int>();\n for (i in Iter.range(1, 100)) {\n l := Deque.pushFront(l, -i);\n l := Deque.pushBack(l, i)\n };\n label F for (i in Iter.revRange(100, -100)) {\n if (i == 0) continue F;\n let x = Deque.peekBack(l);\n switch (Deque.popBack(l)) {\n case (?(l2, y)) {\n l := l2;\n switch x {\n case null assert false;\n case (?x) assert (x == y)\n }\n };\n case null { assert false }\n };\n assert (O.unwrap(x) == i)\n }\n}\n"},"funcTest.mo":{"content":"import Function \"mo:base/Func\";\nimport Debug \"mo:base/Debug\";\nimport Text \"mo:base/Text\";\n\nDebug.print(\"Function\");\n\ndo {\n Debug.print(\" compose\");\n\n func isEven(x : Int) : Bool { x % 2 == 0 };\n func not_(x : Bool) : Bool { not x };\n let isOdd = Function.compose<Int, Bool, Bool>(not_, isEven);\n\n assert (isOdd(0) == false);\n assert (isOdd(1))\n};\n\ndo {\n Debug.print(\" const\");\n\n assert (Function.const<Bool, Text>(true)(\"abc\"));\n assert (Function.const<Bool, Text>(false)(\"abc\") == false);\n assert (Function.const<Bool, (Text, Text)>(false)(\"abc\", \"abc\") == false)\n}\n"},"intTest.mo":{"content":"import Int \"mo:base/Int\";\nimport Order \"mo:base/Order\";\n\nimport Suite \"mo:matchers/Suite\";\nimport T \"mo:matchers/Testable\";\nimport M \"mo:matchers/Matchers\";\n\nlet { run; test; suite } = Suite;\n\nlet largeNumber = 123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000_123_456_789_000;\nlet largeNumberText = \"123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000123456789000\";\n\ntype Order = { #less; #equal; #greater };\n\nclass OrderTestable(value : Order) : T.TestableItem<Order> {\n public let item = value;\n public func display(value : Order) : Text {\n debug_show (value)\n };\n public let equals = func(x : Order, y : Order) : Bool {\n x == y\n }\n};\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"abs\",\n [\n test(\n \"positive number\",\n Int.abs(123),\n M.equals(T.int(123))\n ),\n test(\n \"negative number\",\n Int.abs(-123),\n M.equals(T.int(+123))\n ),\n test(\n \"zero\",\n Int.abs(0),\n M.equals(T.int(0))\n ),\n test(\n \"large positive int\",\n Int.abs(largeNumber),\n M.equals(T.int(largeNumber))\n ),\n test(\n \"large negative int\",\n Int.abs(-largeNumber),\n M.equals(T.int(largeNumber))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"toText\",\n [\n test(\n \"all digits\",\n Int.toText(1234567890),\n M.equals(T.text(\"1234567890\"))\n ),\n test(\n \"positive number\",\n Int.toText(1234),\n M.equals(T.text(\"1234\"))\n ),\n test(\n \"negative number\",\n Int.toText(-1234),\n M.equals(T.text(\"-1234\"))\n ),\n test(\n \"zero\",\n Int.toText(0),\n M.equals(T.text(\"0\"))\n ),\n test(\n \"large number\",\n Int.toText(largeNumber),\n M.equals(T.text(largeNumberText))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"min\",\n [\n test(\n \"both positive\",\n Int.min(2, 3),\n M.equals(T.int(2))\n ),\n test(\n \"positive, negative\",\n Int.min(+2, -3),\n M.equals(T.int(-3))\n ),\n test(\n \"both negative\",\n Int.min(-2, -3),\n M.equals(T.int(-3))\n ),\n test(\n \"negative, positive\",\n Int.min(-2, 3),\n M.equals(T.int(-2))\n ),\n test(\n \"equal values\",\n Int.min(123, 123),\n M.equals(T.int(123))\n ),\n test(\n \"large numbers\",\n Int.min(largeNumber, largeNumber + 1),\n M.equals(T.int(largeNumber))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"max\",\n [\n test(\n \"both positive\",\n Int.max(2, 3),\n M.equals(T.int(3))\n ),\n test(\n \"positive, negative\",\n Int.max(2, -3),\n M.equals(T.int(2))\n ),\n test(\n \"both negative\",\n Int.max(-2, -3),\n M.equals(T.int(-2))\n ),\n test(\n \"negative, positive\",\n Int.max(-2, 3),\n M.equals(T.int(3))\n ),\n test(\n \"equal values\",\n Int.max(+123, 123),\n M.equals(T.int(123))\n ),\n test(\n \"large numbers\",\n Int.max(largeNumber, largeNumber + 1),\n M.equals(T.int(largeNumber + 1))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"equal\",\n [\n test(\n \"positive equal\",\n Int.equal(123, 123),\n M.equals(T.bool(true))\n ),\n test(\n \"negative equal\",\n Int.equal(-123, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"zero\",\n Int.equal(0, 0),\n M.equals(T.bool(true))\n ),\n test(\n \"positive not equal\",\n Int.equal(123, 124),\n M.equals(T.bool(false))\n ),\n test(\n \"negative not equal\",\n Int.equal(-123, -124),\n M.equals(T.bool(false))\n ),\n test(\n \"mixed signs\",\n Int.equal(123, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"large equal\",\n Int.equal(largeNumber, largeNumber),\n M.equals(T.bool(true))\n ),\n test(\n \"large not equal\",\n Int.equal(largeNumber, largeNumber + 1),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"notEqual\",\n [\n test(\n \"positive equal\",\n Int.notEqual(123, 123),\n M.equals(T.bool(false))\n ),\n test(\n \"negative equal\",\n Int.notEqual(-123, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"zero\",\n Int.notEqual(0, 0),\n M.equals(T.bool(false))\n ),\n test(\n \"positive not equal\",\n Int.notEqual(123, 124),\n M.equals(T.bool(true))\n ),\n test(\n \"negative not equal\",\n Int.notEqual(-123, -124),\n M.equals(T.bool(true))\n ),\n test(\n \"mixed signs\",\n Int.notEqual(123, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"large equal\",\n Int.notEqual(largeNumber, largeNumber),\n M.equals(T.bool(false))\n ),\n test(\n \"large not equal\",\n Int.notEqual(largeNumber, largeNumber + 1),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"less\",\n [\n test(\n \"positive equal\",\n Int.less(123, 123),\n M.equals(T.bool(false))\n ),\n test(\n \"positive less\",\n Int.less(123, 245),\n M.equals(T.bool(true))\n ),\n test(\n \"positive greater\",\n Int.less(245, 123),\n M.equals(T.bool(false))\n ),\n test(\n \"negative equal\",\n Int.less(-123, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"negative less\",\n Int.less(-245, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"negative greater\",\n Int.less(-123, -245),\n M.equals(T.bool(false))\n ),\n test(\n \"zero\",\n Int.less(0, 0),\n M.equals(T.bool(false))\n ),\n test(\n \"mixed signs less\",\n Int.less(-123, 123),\n M.equals(T.bool(true))\n ),\n test(\n \"mixed signs greater\",\n Int.less(123, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"large numbers less\",\n Int.less(largeNumber, largeNumber + 1),\n M.equals(T.bool(true))\n ),\n test(\n \"large numbers equal\",\n Int.less(largeNumber, largeNumber),\n M.equals(T.bool(false))\n ),\n test(\n \"large numbers greater\",\n Int.less(largeNumber + 1, largeNumber),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"lessOrEqual\",\n [\n test(\n \"positive equal\",\n Int.lessOrEqual(123, 123),\n M.equals(T.bool(true))\n ),\n test(\n \"positive less\",\n Int.lessOrEqual(123, 245),\n M.equals(T.bool(true))\n ),\n test(\n \"positive greater\",\n Int.lessOrEqual(245, 123),\n M.equals(T.bool(false))\n ),\n test(\n \"negative equal\",\n Int.lessOrEqual(-123, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"negative less\",\n Int.lessOrEqual(-245, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"negative greater\",\n Int.lessOrEqual(-123, -245),\n M.equals(T.bool(false))\n ),\n test(\n \"zero\",\n Int.lessOrEqual(0, 0),\n M.equals(T.bool(true))\n ),\n test(\n \"mixed signs less\",\n Int.lessOrEqual(-123, 123),\n M.equals(T.bool(true))\n ),\n test(\n \"mixed signs greater\",\n Int.lessOrEqual(123, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"large numbers less\",\n Int.lessOrEqual(largeNumber, largeNumber + 1),\n M.equals(T.bool(true))\n ),\n test(\n \"large numbers equal\",\n Int.lessOrEqual(largeNumber, largeNumber),\n M.equals(T.bool(true))\n ),\n test(\n \"large numbers greater\",\n Int.lessOrEqual(largeNumber + 1, largeNumber),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"greater\",\n [\n test(\n \"positive equal\",\n Int.greater(123, 123),\n M.equals(T.bool(false))\n ),\n test(\n \"positive less\",\n Int.greater(123, 245),\n M.equals(T.bool(false))\n ),\n test(\n \"positive greater\",\n Int.greater(245, 123),\n M.equals(T.bool(true))\n ),\n test(\n \"negative equal\",\n Int.greater(-123, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"negative less\",\n Int.greater(-245, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"negative greater\",\n Int.greater(-123, -245),\n M.equals(T.bool(true))\n ),\n test(\n \"zero\",\n Int.greater(0, 0),\n M.equals(T.bool(false))\n ),\n test(\n \"mixed signs less\",\n Int.greater(-123, 123),\n M.equals(T.bool(false))\n ),\n test(\n \"mixed signs greater\",\n Int.greater(123, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"large numbers less\",\n Int.greater(largeNumber, largeNumber + 1),\n M.equals(T.bool(false))\n ),\n test(\n \"large numbers equal\",\n Int.greater(largeNumber, largeNumber),\n M.equals(T.bool(false))\n ),\n test(\n \"large numbers greater\",\n Int.greater(largeNumber + 1, largeNumber),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"greaterOrEqual\",\n [\n test(\n \"positive equal\",\n Int.greaterOrEqual(123, 123),\n M.equals(T.bool(true))\n ),\n test(\n \"positive less\",\n Int.greaterOrEqual(123, 245),\n M.equals(T.bool(false))\n ),\n test(\n \"positive greater\",\n Int.greaterOrEqual(245, 123),\n M.equals(T.bool(true))\n ),\n test(\n \"negative equal\",\n Int.greaterOrEqual(-123, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"negative less\",\n Int.greaterOrEqual(-245, -123),\n M.equals(T.bool(false))\n ),\n test(\n \"negative greater\",\n Int.greaterOrEqual(-123, -245),\n M.equals(T.bool(true))\n ),\n test(\n \"zero\",\n Int.greaterOrEqual(0, 0),\n M.equals(T.bool(true))\n ),\n test(\n \"mixed signs less\",\n Int.greaterOrEqual(-123, 123),\n M.equals(T.bool(false))\n ),\n test(\n \"mixed signs greater\",\n Int.greaterOrEqual(123, -123),\n M.equals(T.bool(true))\n ),\n test(\n \"large numbers less\",\n Int.greaterOrEqual(largeNumber, largeNumber + 1),\n M.equals(T.bool(false))\n ),\n test(\n \"large numbers equal\",\n Int.greaterOrEqual(largeNumber, largeNumber),\n M.equals(T.bool(true))\n ),\n test(\n \"large numbers greater\",\n Int.greaterOrEqual(largeNumber + 1, largeNumber),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"compare\",\n [\n test(\n \"positive equal\",\n Int.compare(123, 123),\n M.equals(OrderTestable(#equal))\n ),\n test(\n \"positive less\",\n Int.compare(123, 245),\n M.equals(OrderTestable(#less))\n ),\n test(\n \"positive greater\",\n Int.compare(245, 123),\n M.equals(OrderTestable(#greater))\n ),\n test(\n \"negative equal\",\n Int.compare(-123, -123),\n M.equals(OrderTestable(#equal))\n ),\n test(\n \"negative less\",\n Int.compare(-245, -123),\n M.equals(OrderTestable(#less))\n ),\n test(\n \"negative greater\",\n Int.compare(-123, -245),\n M.equals(OrderTestable(#greater))\n ),\n test(\n \"zero\",\n Int.compare(0, 0),\n M.equals(OrderTestable(#equal))\n ),\n test(\n \"mixed signs less\",\n Int.compare(-123, 123),\n M.equals(OrderTestable(#less))\n ),\n test(\n \"mixed signs greater\",\n Int.compare(123, -123),\n M.equals(OrderTestable(#greater))\n ),\n test(\n \"large numbers less\",\n Int.compare(largeNumber, largeNumber + 1),\n M.equals(OrderTestable(#less))\n ),\n test(\n \"large numbers equal\",\n Int.compare(largeNumber, largeNumber),\n M.equals(OrderTestable(#equal))\n ),\n test(\n \"large numbers greater\",\n Int.compare(largeNumber + 1, largeNumber),\n M.equals(OrderTestable(#greater))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"neg\",\n [\n test(\n \"positive number\",\n Int.neg(123),\n M.equals(T.int(-123))\n ),\n test(\n \"negative number\",\n Int.neg(-123),\n M.equals(T.int(123))\n ),\n test(\n \"zero\",\n Int.neg(0),\n M.equals(T.int(0))\n ),\n test(\n \"positive large number\",\n Int.neg(largeNumber),\n M.equals(T.int(-largeNumber))\n ),\n test(\n \"negative large number\",\n Int.neg(-largeNumber),\n M.equals(T.int(largeNumber))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"add\",\n [\n test(\n \"positive\",\n Int.add(123, 123),\n M.equals(T.int(246))\n ),\n test(\n \"negative\",\n Int.add(-123, -123),\n M.equals(T.int(-246))\n ),\n test(\n \"mixed signs\",\n Int.add(-123, 223),\n M.equals(T.int(100))\n ),\n test(\n \"zero\",\n Int.add(0, 0),\n M.equals(T.int(0))\n ),\n test(\n \"large addition\",\n Int.add(largeNumber, largeNumber),\n M.equals(T.int(2 * largeNumber))\n ),\n test(\n \"large subtraction\",\n Int.add(largeNumber, -largeNumber),\n M.equals(T.int(0))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"sub\",\n [\n test(\n \"positive\",\n Int.sub(123, 123),\n M.equals(T.int(0))\n ),\n test(\n \"negative\",\n Int.sub(-123, -123),\n M.equals(T.int(0))\n ),\n test(\n \"mixed signs\",\n Int.sub(-123, 223),\n M.equals(T.int(-346))\n ),\n test(\n \"zero\",\n Int.sub(0, 0),\n M.equals(T.int(0))\n ),\n test(\n \"large addition\",\n Int.sub(largeNumber, largeNumber),\n M.equals(T.int(0))\n ),\n test(\n \"large subtraction\",\n Int.sub(largeNumber, -largeNumber),\n M.equals(T.int(2 * largeNumber))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"mul\",\n [\n test(\n \"positive\",\n Int.mul(123, 234),\n M.equals(T.int(28782))\n ),\n test(\n \"negative\",\n Int.mul(-123, -234),\n M.equals(T.int(28782))\n ),\n test(\n \"mixed signs\",\n Int.mul(-123, 234),\n M.equals(T.int(-28782))\n ),\n test(\n \"zeros\",\n Int.mul(0, 0),\n M.equals(T.int(0))\n ),\n test(\n \"zero and large number\",\n Int.mul(0, largeNumber),\n M.equals(T.int(0))\n ),\n test(\n \"large number and zero\",\n Int.mul(largeNumber, 0),\n M.equals(T.int(0))\n ),\n test(\n \"large numbers\",\n Int.mul(largeNumber, largeNumber),\n M.equals(T.int(largeNumber ** 2))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"div\",\n [\n test(\n \"positive multiple\",\n Int.div(156, 13),\n M.equals(T.int(12))\n ),\n test(\n \"positive remainder\",\n Int.div(1234, 100),\n M.equals(T.int(12))\n ),\n test(\n \"negative multiple\",\n Int.div(-156, -13),\n M.equals(T.int(12))\n ),\n test(\n \"negative remainder\",\n Int.div(-1234, -100),\n M.equals(T.int(12))\n ),\n test(\n \"mixed signs\",\n Int.div(-123, 23),\n M.equals(T.int(-5))\n ),\n test(\n \"zero and number\",\n Int.div(0, -123),\n M.equals(T.int(0))\n ),\n test(\n \"zero and large number\",\n Int.div(0, largeNumber),\n M.equals(T.int(0))\n ),\n test(\n \"large number and number\",\n Int.div(largeNumber, 123),\n M.equals(T.int(largeNumber / 123))\n ),\n test(\n \"equal large numbers\",\n Int.div(largeNumber, largeNumber),\n M.equals(T.int(1))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"rem\",\n [\n test(\n \"positive multiple\",\n Int.rem(156, 13),\n M.equals(T.int(0))\n ),\n test(\n \"positive/positive remainder\",\n Int.rem(1234, 100),\n M.equals(T.int(34))\n ),\n test(\n \"positive/negative remainder\",\n Int.rem(1234, -100),\n M.equals(T.int(34))\n ),\n test(\n \"negative multiple\",\n Int.rem(-156, -13),\n M.equals(T.int(0))\n ),\n test(\n \"negative/positive remainder\",\n Int.rem(-1234, 100),\n M.equals(T.int(-34))\n ),\n test(\n \"negative/negative remainder\",\n Int.rem(-1234, -100),\n M.equals(T.int(-34))\n ),\n test(\n \"zero and large number\",\n Int.rem(0, largeNumber),\n M.equals(T.int(0))\n ),\n test(\n \"large number and number\",\n Int.rem(largeNumber * 123 + 100, 123),\n M.equals(T.int(100))\n ),\n test(\n \"equal large numbers\",\n Int.rem(largeNumber, largeNumber),\n M.equals(T.int(0))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nrun(\n suite(\n \"pow\",\n [\n test(\n \"positive base, positive exponent\",\n Int.pow(72, 3),\n M.equals(T.int(373248))\n ),\n test(\n \"positive base, zero exponent\",\n Int.pow(72, 0),\n M.equals(T.int(1))\n ),\n test(\n \"negative base, positive exponent\",\n Int.pow(-72, 3),\n M.equals(T.int(-373248))\n ),\n test(\n \"negative base, zero exponent\",\n Int.pow(-72, 0),\n M.equals(T.int(1))\n ),\n test(\n \"large number and zero\",\n Int.pow(largeNumber, 0),\n M.equals(T.int(1))\n ),\n test(\n \"positive large number and small number\",\n Int.pow(largeNumber, 3),\n M.equals(T.int(largeNumber * largeNumber * largeNumber))\n ),\n test(\n \"negative large number and small number\",\n Int.pow(-largeNumber, 2),\n M.equals(T.int(largeNumber * largeNumber))\n ),\n test(\n \"one and max Nat\",\n Int.pow(1, 2 ** 32 - 1),\n M.equals(T.int(1))\n ),\n test(\n \"zero and max Nat\",\n Int.pow(0, 2 ** 32 - 1),\n M.equals(T.int(0))\n )\n ]\n )\n)\n"},"errorTest.mo":{"content":"import Error \"mo:base/Error\";\n\nimport Suite \"mo:matchers/Suite\";\nimport T \"mo:matchers/Testable\";\nimport M \"mo:matchers/Matchers\";\n\nlet { run; test; suite } = Suite;\n\nclass ErrorCodeTestable() : T.Testable<Error.ErrorCode> {\n public func display(code : Error.ErrorCode) : Text {\n debug_show (code)\n };\n public func equals(first : Error.ErrorCode, second : Error.ErrorCode) : Bool {\n first == second\n }\n};\n\nlet testMessage = \"Test error message\";\n\nrun(\n suite(\n \"reject\",\n [\n test(\n \"error code\",\n Error.code(Error.reject(testMessage)),\n M.equals({ { item = #canister_reject } and ErrorCodeTestable() })\n ),\n test(\n \"error message\",\n Error.message(Error.reject(testMessage)),\n M.equals(T.text(testMessage))\n )\n ]\n )\n)\n"},"iterTest.mo":{"content":"import Iter \"mo:base/Iter\";\nimport Array \"mo:base/Array\";\nimport List \"mo:base/List\";\nimport Nat \"mo:base/Nat\";\nimport Int \"mo:base/Int\";\nimport Debug \"mo:base/Debug\";\n\nDebug.print(\"Iter\");\n\ndo {\n Debug.print(\" range\");\n\n let tests = [((0, -1), \"\", \"0-1\"), ((0, 0), \"0\", \"0\"), ((0, 5), \"012345\", \"\"), ((5, 0), \"\", \"543210\")];\n for ((range, expected, revExpected) in tests.vals()) {\n var x = \"\";\n for (i in Iter.range(range)) {\n x := x # Nat.toText(i)\n };\n assert (x == expected);\n x := \"\";\n for (i in Iter.revRange(range)) {\n x := x # Int.toText(i)\n };\n assert (x == revExpected)\n }\n};\n\ndo {\n Debug.print(\" iterate\");\n\n let xs = [\"a\", \"b\", \"c\", \"d\", \"e\", \"f\"];\n\n var y = \"\";\n var z = 0;\n\n Iter.iterate<Text>(\n xs.vals(),\n func(x : Text, i : Nat) {\n y := y # x;\n z += i\n }\n );\n\n assert (y == \"abcdef\");\n assert (z == 15)\n};\n\ndo {\n Debug.print(\" map\");\n\n let isEven = func(x : Int) : Bool {\n x % 2 == 0\n };\n\n let _actual = Iter.map<Nat, Bool>([1, 2, 3].vals(), isEven);\n let actual = [var true, false, true];\n Iter.iterate<Bool>(_actual, func(x, i) { actual[i] := x });\n\n let expected = [false, true, false];\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" filter\");\n\n let isOdd = func(x : Int) : Bool {\n x % 2 == 1\n };\n\n let _actual = Iter.filter<Nat>([1, 2, 3].vals(), isOdd);\n let actual = [var 0, 0];\n Iter.iterate<Nat>(_actual, func(x, i) { actual[i] := x });\n\n let expected = [1, 3];\n\n assert (Array.freeze(actual) == expected)\n};\n\ndo {\n Debug.print(\" make\");\n\n let x = 1;\n let y = Iter.make<Nat>(x);\n\n switch (y.next()) {\n case null { assert false };\n case (?z) { assert (x == z) }\n }\n};\n\ndo {\n Debug.print(\" fromArray\");\n\n let expected = [1, 2, 3];\n let _actual = Iter.fromArray<Nat>(expected);\n let actual = [var 0, 0, 0];\n\n Iter.iterate<Nat>(_actual, func(x, i) { actual[i] := x });\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" fromArrayMut\");\n\n let expected = [var 1, 2, 3];\n let _actual = Iter.fromArrayMut<Nat>(expected);\n let actual = [var 0, 0, 0];\n\n Iter.iterate<Nat>(_actual, func(x, i) { actual[i] := x });\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" fromList\");\n\n let list : List.List<Nat> = ?(1, ?(2, ?(3, List.nil<Nat>())));\n let _actual = Iter.fromList<Nat>(list);\n let actual = [var 0, 0, 0];\n let expected = [1, 2, 3];\n\n Iter.iterate<Nat>(_actual, func(x, i) { actual[i] := x });\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" toArray\");\n\n let expected = [1, 2, 3];\n let actual = Iter.toArray<Nat>(expected.vals());\n\n assert (actual.size() == expected.size());\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" toArrayMut\");\n\n let expected = [var 1, 2, 3];\n let actual = Iter.toArrayMut<Nat>(expected.vals());\n\n assert (actual.size() == expected.size());\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" toList\");\n\n let expected : List.List<Nat> = ?(1, ?(2, ?(3, List.nil<Nat>())));\n let actual = Iter.toList<Nat>([1, 2, 3].vals());\n assert List.equal<Nat>(expected, actual, func(x1, x2) { x1 == x2 })\n};\n\ndo {\n Debug.print(\" sort\");\n\n let input : [Nat] = [4, 3, 1, 2, 5];\n let expected : [Nat] = [1, 2, 3, 4, 5];\n let actual = Iter.toArray(Iter.sort<Nat>(input.vals(), Nat.compare));\n assert Array.equal<Nat>(expected, actual, func(x1, x2) { x1 == x2 })\n}\n"},"noneTest.mo":{"content":"import Array \"mo:base/Array\";\nimport None \"mo:base/None\";\nimport Debug \"mo:base/Debug\";\n\nDebug.print(\"None\");\n\ndo {\n Debug.print(\" impossible\");\n\n func showNone(x : None) : Text {\n None.impossible<Text>(x)\n }\n}\n"},"listTest.mo":{"content":"import List \"mo:base/List\";\nimport Nat \"mo:base/Nat\";\nimport Order \"mo:base/Order\";\nimport Debug \"mo:base/Debug\";\nimport Int \"mo:base/Int\";\nimport Iter \"mo:base/Iter\";\nimport Result \"mo:base/Result\";\nimport Suite \"mo:matchers/Suite\";\nimport M \"mo:matchers/Matchers\";\nimport T \"mo:matchers/Testable\";\n\n/*\n\nFIXME:\n\n* flatten is quadratic\n* Array.mo doesn't implement `all`, `some`, `compare`\n* merge takes lte predicate of type (T,T)-> Bool, not comparison of type: (T,T) -> Ord\n* split is not tail recursive and calls redundant helpers\n\nTODO:\n * most of these test don't test evaluation order or short-circuiting.\n * from/to(Var)Array functions could use matchers tests beyond the existing assert only tests\n*/\n\nfunc ordT(o : Order.Order) : T.TestableItem<Order.Order> = {\n item = o;\n display = func(o : Order.Order) : Text { debug_show (o) };\n equals = Order.equal\n};\n\ntype X = Nat;\n\nfunc opnatEq(a : ?Nat, b : ?Nat) : Bool {\n switch (a, b) {\n case (null, null) { true };\n case (?aaa, ?bbb) { aaa == bbb };\n case (_, _) { false }\n }\n};\nfunc opnat_isnull(a : ?Nat) : Bool {\n switch a {\n case (null) { true };\n case (?aaa) { false }\n }\n};\n\n// ## Construction\nlet l1 = List.nil<X>();\nlet l2 = List.push<X>(2, l1);\nlet l3 = List.push<X>(3, l2);\n\n// ## Projection -- use nth\nassert (opnatEq(List.get<X>(l3, 0), ?3));\nassert (opnatEq(List.get<X>(l3, 1), ?2));\nassert (opnatEq(List.get<X>(l3, 2), null));\n//assert (opnatEq (hd<X>(l3), ?3));\n//assert (opnatEq (hd<X>(l2), ?2));\n//assert (opnat_isnull(hd<X>(l1)));\n\n/*\n // ## Projection -- use nth\n assert (opnatEq(nth<X>(l3, 0), ?3));\n assert (opnatEq(nth<X>(l3, 1), ?2));\n assert (opnatEq(nth<X>(l3, 2), null));\n assert (opnatEq (hd<X>(l3), ?3));\n assert (opnatEq (hd<X>(l2), ?2));\n assert (opnat_isnull(hd<X>(l1)));\n */\n\n// ## Deconstruction\nlet (a1, t1) = List.pop<X>(l3);\nassert (opnatEq(a1, ?3));\nlet (a2, t2) = List.pop<X>(l2);\nassert (opnatEq(a2, ?2));\nlet (a3, t3) = List.pop<X>(l1);\nassert (opnatEq(a3, null));\nassert (List.isNil<X>(t3));\n\n// ## List functions\nassert (List.size<X>(l1) == 0);\nassert (List.size<X>(l2) == 1);\nassert (List.size<X>(l3) == 2);\n\n// ## List functions\nassert (List.size<X>(l1) == 0);\nassert (List.size<X>(l2) == 1);\nassert (List.size<X>(l3) == 2);\n\ndo {\n Debug.print(\" flatten\");\n\n let expected : List.List<Nat> = ?(1, ?(2, ?(3, null)));\n // [[1, 2], [3]]\n let nested : List.List<List.List<Nat>> = ?(?(1, ?(2, null)), ?(?(3, null), null));\n let actual = List.flatten<Nat>(nested);\n\n assert List.equal<Nat>(expected, actual, func(x1, x2) { x1 == x2 });\n\n};\n\ndo {\n Debug.print(\" fromArray\");\n\n let expected : List.List<Nat> = ?(1, ?(2, ?(3, List.nil<Nat>())));\n let array = [1, 2, 3];\n let actual = List.fromArray<Nat>(array);\n\n assert List.equal<Nat>(expected, actual, func(x1, x2) { x1 == x2 })\n};\n\ndo {\n Debug.print(\" fromVarArray\");\n\n let expected : List.List<Nat> = ?(1, ?(2, ?(3, List.nil<Nat>())));\n let array = [var 1, 2, 3];\n let actual = List.fromVarArray<Nat>(array);\n\n assert List.equal<Nat>(expected, actual, func(x1, x2) { x1 == x2 })\n};\n\ndo {\n Debug.print(\" toArray\");\n\n let expected = [1, 2, 3];\n let list : List.List<Nat> = ?(1, ?(2, ?(3, List.nil<Nat>())));\n let actual = List.toArray<Nat>(list);\n\n assert (actual.size() == expected.size());\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" toVarArray\");\n\n let expected = [var 1, 2, 3];\n let list : List.List<Nat> = ?(1, ?(2, ?(3, List.nil<Nat>())));\n let actual = List.toVarArray<Nat>(list);\n\n assert (actual.size() == expected.size());\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\ndo {\n Debug.print(\" toIter\");\n\n let list : List.List<Nat> = ?(1, ?(2, ?(3, List.nil<Nat>())));\n let _actual = List.toIter<Nat>(list);\n let actual = [var 0, 0, 0];\n let expected = [1, 2, 3];\n\n Iter.iterate<Nat>(_actual, func(x, i) { actual[i] := x });\n\n for (i in actual.keys()) {\n assert (actual[i] == expected[i])\n }\n};\n\nfunc makeNatural(x : Int) : Result.Result<Nat, Text> = if (x >= 0) {\n #ok(Int.abs(x))\n} else { #err(Int.toText(x) # \" is not a natural number.\") };\n\nfunc listRes(itm : Result.Result<List.List<Nat>, Text>) : T.TestableItem<Result.Result<List.List<Nat>, Text>> {\n let resT = T.resultTestable(T.listTestable<Nat>(T.intTestable), T.textTestable);\n { display = resT.display; equals = resT.equals; item = itm }\n};\n\n\n\nlet mapResult = Suite.suite(\n \"mapResult\",\n [\n Suite.test(\n \"empty list\",\n List.mapResult<Int, Nat, Text>(List.nil(), makeNatural),\n M.equals(listRes(#ok(List.nil())))\n ),\n Suite.test(\n \"success\",\n List.mapResult<Int, Nat, Text>(?(1, ?(2, ?(3, null))), makeNatural),\n M.equals(listRes(#ok(?(1, ?(2, ?(3, null))))))\n ),\n Suite.test(\n \"fail fast\",\n List.mapResult<Int, Nat, Text>(?(-1, ?(2, ?(3, null))), makeNatural),\n M.equals(listRes(#err(\"-1 is not a natural number.\")))\n ),\n Suite.test(\n \"fail last\",\n List.mapResult<Int, Nat, Text>(?(1, ?(2, ?(-3, null))), makeNatural),\n M.equals(listRes(#err(\"-3 is not a natural number.\")))\n )\n ]\n);\n\nSuite.run(Suite.suite(\"List\", [mapResult]));\n\nlet replicate = Suite.suite(\n \"replicate\",\n [\n Suite.test(\n \"empty-list\",\n List.replicate<Nat>(0, 0),\n M.equals(\n T.list(T.natTestable, List.nil<Nat>())\n )\n ),\n Suite.test(\n \"small-list\",\n List.replicate(3, 0),\n M.equals(\n T.list<Nat>(T.natTestable, ?(0, ?(0, ?(0, null))))\n )\n )\n ]\n);\n\nlet tabulate = Suite.suite(\n \"tabulate\",\n [\n Suite.test(\n \"empty-list\",\n List.tabulate<Nat>(0, func i { i }),\n M.equals(\n T.list(T.natTestable, List.nil<Nat>())\n )\n ),\n Suite.test(\n \"small-list\",\n List.tabulate<Nat>(3, func i { i * 2 }),\n M.equals(\n T.list<Nat>(T.natTestable, ?(0, ?(2, ?(4, null))))\n )\n ),\n Suite.test(\n \"large-list\",\n List.tabulate<Nat>(10000, func i { 0 }),\n M.equals(\n T.list<Nat>(T.natTestable, List.replicate(10000, 0))\n )\n )\n ]\n);\n\nlet append = Suite.suite(\n \"append\",\n [\n Suite.test(\n \"small-list\",\n List.append(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(10, func i { i + 10 })\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(20, func i { i }))\n )\n ),\n Suite.test(\n \"large-list\",\n List.append(\n List.tabulate<Nat>(10000, func i { i }),\n List.tabulate<Nat>(10000, func i { i + 10000 })\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(20000, func i { i }))\n )\n )\n ]\n);\n\nlet isNil = Suite.suite(\n \"isNil\",\n [\n Suite.test(\n \"empty\",\n List.isNil(List.nil<Nat>()),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"singleton\",\n List.isNil(?(3, null)),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"nary\",\n List.isNil(?(1, ?(2, ?(3, null)))),\n M.equals(T.bool(false))\n )\n ]\n);\n\nlet push = Suite.suite(\n \"push\",\n [\n Suite.test(\n \"empty\",\n List.push(0, List.nil<Nat>()),\n M.equals(T.list(T.natTestable, ?(0, null)))\n ),\n Suite.test(\n \"singleton\",\n List.push(1, List.push(0, List.nil<Nat>())),\n M.equals(T.list(T.natTestable, ?(1, ?(0, null))))\n ),\n Suite.test(\n \"nary\",\n List.push(2, List.push(1, List.push(0, List.nil<Nat>()))),\n M.equals(T.list(T.natTestable, ?(2, ?(1, ?(0, null)))))\n )\n ]\n);\n\n\nlet last = Suite.suite(\n \"last\",\n [\n Suite.test(\n \"empty list\",\n List.last(List.nil<Nat>()),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"singleton\",\n List.last(?(3, null)),\n M.equals(T.optional(T.natTestable, ?3))\n ),\n Suite.test(\n \"threesome\",\n List.last(?(1, ?(2, ?(3, null)))),\n M.equals(T.optional(T.natTestable, ?3))\n )\n ]\n);\n\nlet pop = Suite.suite(\n \"pop\",\n [\n Suite.test(\n \"empty list\",\n List.pop(List.nil<Nat>()),\n M.equals(T.tuple2(T.optionalTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (null, null) : (?Nat, List.List<Nat>) ))\n ),\n Suite.test(\n \"singleton\",\n List.pop(?(3, null)),\n M.equals(T.tuple2(T.optionalTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (?3, null) : (?Nat, List.List<Nat>) ))\n ),\n Suite.test(\n \"threesome\",\n List.pop(?(1, ?(2, ?(3, null)))),\n M.equals(T.tuple2(T.optionalTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (?1, ?(2, ?(3, null))) : (?Nat, List.List<Nat>) ))\n ),\n ]\n);\n\nlet size = Suite.suite(\n \"size\",\n [\n Suite.test(\n \"empty list\",\n List.size(List.nil<Nat>()),\n M.equals(T.nat(0))\n ),\n Suite.test(\n \"singleton\",\n List.size(?(3, null)),\n M.equals(T.nat(1))\n ),\n Suite.test(\n \"threesome\",\n List.size(?(1, ?(2, ?(3, null)))),\n M.equals(T.nat(3))\n ),\n ]\n);\n\nlet get = Suite.suite(\n \"get\",\n [\n Suite.test(\n \"empty list\",\n List.get(List.nil<Nat>(), 0),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"singleton-0\",\n List.get(?(3, null), 0),\n M.equals(T.optional(T.natTestable, ?3 : ?Nat))\n ),\n Suite.test(\n \"singleton-1\",\n List.get(?(3, null), 1),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"singleton-2\",\n List.get(?(3, null), 2),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"threesome-0\",\n List.get(?(1, ?(2, ?(3, null))), 0),\n M.equals(T.optional(T.natTestable, ?1 : ?Nat))\n ),\n Suite.test(\n \"threesome-1\",\n List.get(?(1, ?(2, ?(3, null))), 1),\n M.equals(T.optional(T.natTestable, ?2 : ?Nat))\n ),\n Suite.test(\n \"threesome-3\",\n List.get(?(1, ?(2, ?(3, null))), 3),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"threesome-4\",\n List.get(?(1, ?(2, ?(3, null))), 4),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n )\n ]\n);\n\n\nlet reverse = Suite.suite(\n \"reverse\",\n [\n Suite.test(\n \"empty list\",\n List.reverse(List.nil<Nat>()),\n M.equals(T.list(T.natTestable, null : List.List<Nat>))\n\n ),\n Suite.test(\n \"singleton\",\n List.reverse(?(3, null)),\n M.equals(T.list(T.natTestable, ?(3, null)))\n ),\n Suite.test(\n \"threesome\",\n List.reverse(?(1, ?(2, ?(3, null)))),\n M.equals(T.list(T.natTestable, ?(3, ?(2, ?(1, null)))))\n ),\n ]\n);\n\nlet iterate = Suite.suite(\n \"iterate\",\n [\n Suite.test(\n \"empty list\",\n do {\n var t = \"\";\n List.iterate<Nat>(List.nil<Nat>(), func n { t #= debug_show n });\n t\n },\n M.equals(T.text(\"\"))\n ),\n Suite.test(\n \"singleton\",\n do {\n var t = \"\";\n List.iterate<Nat>(?(3, null), func n { t #= debug_show n });\n t\n },\n M.equals(T.text(\"3\"))\n ),\n Suite.test(\n \"threesome\",\n do {\n var t = \"\";\n List.iterate<Nat>(?(1, ?(2, ?(3, null))), func n { t #= debug_show n });\n t\n },\n M.equals(T.text(\"123\"))\n ),\n ]\n);\n\nlet map = Suite.suite(\n \"map\",\n [\n Suite.test(\n \"empty list\",\n List.map<Nat,Nat>(\n List.nil<Nat>(),\n func n { n + 1 }),\n M.equals(T.list(T.natTestable, null : List.List<Nat>))\n ),\n Suite.test(\n \"singleton\",\n List.map<Nat,Nat>(\n ?(3, null),\n func n { n + 1 }),\n M.equals(T.list(T.natTestable, ?(4, null)))\n ),\n Suite.test(\n \"threesome\",\n List.map<Nat,Nat>(\n ?(1, ?(2, ?(3, null))),\n func n { n + 1 }),\n M.equals(T.list(T.natTestable, ?(2, ?(3, ?(4, null)))))\n ),\n ]\n);\n\n\nlet filter = Suite.suite(\n \"filter\",\n [\n Suite.test(\n \"empty list\",\n List.filter<Nat>(\n List.nil<Nat>(),\n func n { n % 2 == 0 }),\n M.equals(T.list(T.natTestable, null : List.List<Nat>))\n ),\n Suite.test(\n \"singleton\",\n List.filter<Nat>(\n ?(3, null),\n func n { n % 2 == 0 }),\n M.equals(T.list(T.natTestable, null : List.List<Nat>))\n ),\n Suite.test(\n \"threesome\",\n List.filter<Nat>(\n ?(1, ?(2, ?(3, null))),\n func n { n % 2 == 0 }),\n M.equals(T.list(T.natTestable, ?(2, null)))\n ),\n Suite.test(\n \"foursome\",\n List.filter<Nat>(\n ?(1, ?(2, ?(3, ?(4, null)))),\n func n { n % 2 == 0 }),\n M.equals(T.list(T.natTestable, ?(2, ?(4, null))))\n ),\n ]\n);\n\nlet partition = Suite.suite(\n \"partition\",\n [\n Suite.test(\n \"empty list\",\n List.partition<Nat>(\n List.nil<Nat>(),\n func n { n % 2 == 0 }),\n M.equals(T.tuple2(T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (null, null) : (List.List<Nat>, List.List<Nat>)))\n ),\n Suite.test(\n \"singleton-false\",\n List.partition<Nat>(\n ?(3, null),\n func n { n % 2 == 0 }),\n M.equals(T.tuple2(T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (null, ?(3, null)) : (List.List<Nat>, List.List<Nat>)))\n\n ),\n Suite.test(\n \"singleton-true\",\n List.partition<Nat>(\n ?(2, null),\n func n { n % 2 == 0 }),\n M.equals(T.tuple2(T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (?(2, null), null) : (List.List<Nat>, List.List<Nat>)))\n ),\n Suite.test(\n \"threesome\",\n List.partition<Nat>(\n ?(1, ?(2, ?(3, null))),\n func n { n % 2 == 0 }),\n M.equals(T.tuple2(T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (?(2, null), ?(1, ?(3, null))) : (List.List<Nat>, List.List<Nat>)))\n ),\n Suite.test(\n \"foursome\",\n List.partition<Nat>(\n ?(1, ?(2, ?(3, ?(4, null)))),\n func n { n % 2 == 0 }),\n M.equals(T.tuple2(T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (?(2, ?(4, null)),\n ?(1, ?(3, null))) : (List.List<Nat>, List.List<Nat>)))\n ),\n ]\n);\n\n\nlet mapFilter = Suite.suite(\n \"mapFilter\",\n [\n Suite.test(\n \"empty list\",\n List.mapFilter<Nat, Text>(\n List.nil<Nat>(),\n func n { if (n % 2 == 0) ?(debug_show n) else null }),\n M.equals(T.list(T.textTestable, null : List.List<Text>))\n ),\n Suite.test(\n \"singleton\",\n List.mapFilter<Nat, Text>(\n ?(3, null),\n func n { if (n % 2 == 0) ?(debug_show n) else null }),\n M.equals(T.list(T.textTestable, null : List.List<Text>))\n ),\n Suite.test(\n \"threesome\",\n List.mapFilter<Nat, Text>(\n ?(1, ?(2, ?(3, null))),\n func n { if (n % 2 == 0) ?(debug_show n) else null }),\n M.equals(T.list(T.textTestable, ?(\"2\", null)))\n ),\n Suite.test(\n \"foursome\",\n List.mapFilter<Nat, Text>(\n ?(1, ?(2, ?(3, ?(4, null)))),\n func n { if (n % 2 == 0) ?(debug_show n) else null }),\n M.equals(T.list(T.textTestable, ?(\"2\", ?(\"4\", null))))\n ),\n ]\n);\n\n\nlet flatten = Suite.suite(\n \"flatten\",\n [\n Suite.test(\n \"small-list\",\n List.flatten(\n List.tabulate<List.List<Nat>>(10, func i { List.tabulate<Nat>(10, func j { i * 10 + j })})\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(100, func i { i }))\n )\n ),\n Suite.test(\n \"small-nulls\",\n List.flatten(\n List.tabulate<List.List<Nat>>(10, func i { null : List.List<Nat> })\n ),\n M.equals(\n T.list(T.natTestable, null : List.List<Nat>)\n )\n ),\n Suite.test(\n \"flatten\",\n List.flatten<Int>(?(?(1, ?(2, ?(3, null))),\n ?(null,\n ?(?(1, null),\n null)))),\n M.equals(T.list<Int>(T.intTestable, ?(1, ?(2, ?(3, ?(1, null))))))\n ),\n Suite.test(\n \"flatten empty start\",\n List.flatten<Int>(?(null,\n ?(?(1, ?(2, (?(3, null)))),\n ?(null,\n ?(?(1, null),\n null))))),\n M.equals(T.list<Int>(T.intTestable, ?(1, ?(2, ?(3, ?(1, null))))))\n ),\n Suite.test(\n \"flatten empty end\",\n List.flatten<Int>(?(?(1, ?(2, (?(3, null)))),\n ?(null,\n ?(?(1, null),\n ?(null,\n null))))),\n M.equals(T.list<Int>(T.intTestable, ?(1, ?(2, ?(3, ?(1, null))))))\n ),\n Suite.test(\n \"flatten singleton\",\n List.flatten<Int>(?(?(1, ?(2, (?(3, null)))),\n null)),\n M.equals(T.list<Int>(T.intTestable, ?(1, ?(2, (?(3, null))))))\n ),\n Suite.test(\n \"flatten singleton empty\",\n List.flatten<Int>(?(null, null)),\n M.equals(T.list<Int>(T.intTestable, null))\n ),\n Suite.test(\n \"flatten empty\",\n List.flatten<Int>(null),\n M.equals(T.list<Int>(T.intTestable, null))\n ),\n ]\n);\n\nlet make = Suite.suite(\n \"make\",\n [\n Suite.test(\n \"make\",\n List.make<Int>(0),\n M.equals(T.list<Int>(T.intTestable, ?(0, null)))\n ),\n ]\n);\n\nlet take = Suite.suite(\n \"take\",\n [\n Suite.test(\n \"empty list\",\n List.take(List.nil<Nat>(), 0),\n M.equals(T.list<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"singleton-0\",\n List.take(?(3, null), 0),\n M.equals(T.list<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"singleton-1\",\n List.take(?(3, null), 1),\n M.equals(T.list(T.natTestable, ?(3, null)))\n ),\n Suite.test(\n \"singleton-2\",\n List.take(?(3, null), 2),\n M.equals(T.list(T.natTestable, ?(3, null)))\n ),\n Suite.test(\n \"threesome-0\",\n List.take(?(1, ?(2, ?(3, null))), 0),\n M.equals(T.list(T.natTestable, null : List.List<Nat>))\n ),\n Suite.test(\n \"threesome-1\",\n List.take(?(1, ?(2, ?(3, null))), 1),\n M.equals(T.list(T.natTestable, ?(1, null)))\n ),\n Suite.test(\n \"threesome-3\",\n List.take(?(1, ?(2, ?(3, null))), 3),\n M.equals(T.list(T.natTestable, ?(1, ?(2, ?(3, null)))))\n ),\n Suite.test(\n \"threesome-4\",\n List.take(?(1, ?(2, ?(3, null))), 4),\n M.equals(T.list(T.natTestable, ?(1, ?(2, ?(3, null)))))\n )\n ]\n);\n\nlet drop = Suite.suite(\n \"drop\",\n [\n Suite.test(\n \"empty list\",\n List.drop(List.nil<Nat>(), 0),\n M.equals(T.list<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"singleton-0\",\n List.drop(?(3, null), 0),\n M.equals(T.list<Nat>(T.natTestable, ?(3,null)))\n ),\n Suite.test(\n \"singleton-1\",\n List.drop(?(3, null), 1),\n M.equals(T.list<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"singleton-2\",\n List.drop(?(3, null), 2),\n M.equals(T.list<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"threesome-0\",\n List.drop(?(1, ?(2, ?(3, null))), 0),\n M.equals(T.list<Nat>(T.natTestable, ?(1, ?(2, ?(3, null)))))\n ),\n Suite.test(\n \"threesome-1\",\n List.drop(?(1, ?(2, ?(3, null))), 1),\n M.equals(T.list(T.natTestable, ?(2, ?(3, null))))\n ),\n Suite.test(\n \"threesome-2\",\n List.drop(?(1, ?(2, ?(3, null))), 2),\n M.equals(T.list(T.natTestable, ?(3, null)))\n ),\n Suite.test(\n \"threesome-3\",\n List.drop(?(1, ?(2, ?(3, null))), 3),\n M.equals(T.list<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"threesome-4\",\n List.drop(?(1, ?(2, ?(3, null))), 4),\n M.equals(T.list<Nat>(T.natTestable, null))\n )\n ]\n);\n\nlet foldLeft = Suite.suite(\n \"foldLeft\", [\n Suite.test(\n \"foldLeft\",\n List.foldLeft<Text, Text>(?(\"a\", ?(\"b\", ?(\"c\", null))), \"\", func(acc, x) = acc # x),\n M.equals(T.text(\"abc\"))\n ),\n Suite.test(\n \"foldLeft empty\",\n List.foldLeft<Text, Text>(null, \"base\", func(x, acc) = acc # x),\n M.equals(T.text(\"base\"))\n ),\n ]\n);\n\nlet foldRight = Suite.suite(\n \"foldRight\", [\n Suite.test(\n \"foldRight\",\n List.foldRight<Text, Text>(?(\"a\", ?(\"b\", ?(\"c\", null))), \"\", func(x, acc) = acc # x),\n M.equals(T.text(\"cba\"))\n ),\n Suite.test(\n \"foldRight empty\",\n List.foldRight<Text, Text>(null, \"base\", func(x, acc) = acc # x),\n M.equals(T.text(\"base\"))\n ),\n ]\n);\n\nlet find = Suite.suite(\n \"find\", [\n Suite.test(\n \"find\",\n List.find<Nat>(?(1, ?(9, ?(4, ?(8, null)))), func x = x == 9),\n M.equals(T.optional(T.natTestable, ?9))\n ),\n Suite.test(\n \"find fail\",\n List.find<Nat>(?(1, ?(9, ?(4, ?(8, null)))), func _ = false),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"find empty\",\n List.find<Nat>(null, func _ = true),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n ]\n);\n\nlet all = Suite.suite(\n \"all\", [\n Suite.test(\n \"all non-empty true\",\n List.all<Nat>(?(1, ?(9, ?(4, ?(8, null)))), func x = x > 0),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"all non-empty false\",\n List.all<Nat>(?(1, ?(9, ?(4, ?(8, null)))), func x = x > 1),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"all empty\",\n List.all<Nat>(null, func x = x >= 1),\n M.equals(T.bool(true))\n ),\n ]\n);\n\nlet some = Suite.suite(\n \"some\", [\n Suite.test(\n \"non-empty true\",\n List.some<Nat>(?(1, ?(9, ?(4, ?(8, null)))), func x = x >= 8),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"non-empty false\",\n List.some<Nat>(?(1, ?(9, ?(4, ?(8, null)))), func x = x > 9),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"empty\",\n List.some<Nat>(null, func x = true),\n M.equals(T.bool(false))\n ),\n ]\n);\n\n\nlet merge = Suite.suite(\n \"merge\",\n [\n Suite.test(\n \"small-list\",\n List.merge<Nat>(\n List.tabulate<Nat>(10, func i { 2 * i }),\n List.tabulate<Nat>(10, func i { 2 * i + 1 }),\n func (i, j) { i <= j }\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(20, func i { i }))\n )\n ),\n\n Suite.test(\n \"small-list-alternating\",\n List.merge<Nat>(\n List.tabulate<Nat>(10, func i {\n if (i % 2 == 0)\n { 2 * i }\n else\n { 2 * i + 1 } }),\n List.tabulate<Nat>(10, func i {\n if (not (i % 2 == 0)) // flipped!\n { 2 * i }\n else\n { 2 * i + 1 }\n }),\n func (i, j) { i <= j }\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(20, func i { i }))\n )\n ),\n\n Suite.test(\n \"small-list-equal\",\n List.merge<Nat>(\n List.tabulate<Nat>(10, func i { 2 * i }),\n List.tabulate<Nat>(10, func i { 2 * i }),\n func (i, j) { i <= j }\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(20, func i { 2 * (i / 2) }))\n )\n ),\n\n Suite.test(\n \"large-list\",\n List.merge<Nat>(\n List.tabulate<Nat>(1000, func i { 2 * i }),\n List.tabulate<Nat>(1000, func i { 2 * i + 1 }),\n func (i, j) { i <= j }\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(2000, func i { i }))\n )\n )\n ]\n);\n\n\nlet compare = Suite.suite(\n \"compare\",\n [\n Suite.test(\n \"small-list-equal\",\n List.compare<Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(10, func i { i }),\n Nat.compare\n ),\n M.equals(ordT(#equal))\n ),\n Suite.test(\n \"small-list-less\",\n List.compare<Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(11, func i { i }),\n Nat.compare\n ),\n M.equals(ordT(#less))\n ),\n Suite.test(\n \"small-list-less\",\n List.compare<Nat>(\n List.tabulate<Nat>(11, func i { i }),\n List.tabulate<Nat>(10, func i { i }),\n Nat.compare\n ),\n M.equals(ordT(#greater))\n ),\n Suite.test(\n \"empty-list-equal\",\n List.compare<Nat>(\n null,\n null,\n Nat.compare\n ),\n M.equals(ordT(#equal))\n ),\n Suite.test(\n \"small-list-less\",\n List.compare<Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(10, func i { if (i < 9) { i } else { i + 1 } }),\n Nat.compare\n ),\n M.equals(ordT(#less))\n ),\n Suite.test(\n \"small-list-greater\",\n List.compare<Nat>(\n List.tabulate<Nat>(10, func i { if (i < 9) { i } else { i + 1 } }),\n List.tabulate<Nat>(10, func i { i }),\n Nat.compare\n ),\n M.equals(ordT(#greater))\n ),\n ]\n);\n\nlet equal = Suite.suite(\n \"equal\",\n [\n Suite.test(\n \"small-list-equal\",\n List.equal<Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(10, func i { i }),\n Nat.equal\n ),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"small-list-less\",\n List.equal<Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(11, func i { i }),\n Nat.equal\n ),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"small-list-less\",\n List.equal<Nat>(\n List.tabulate<Nat>(11, func i { i }),\n List.tabulate<Nat>(10, func i { i }),\n Nat.equal\n ),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"empty-list-equal\",\n List.equal<Nat>(\n null,\n null,\n Nat.equal\n ),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"small-list-less\",\n List.equal<Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(10, func i { if (i < 9) { i } else { i + 1 } }),\n Nat.equal\n ),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"small-list-greater\",\n List.equal<Nat>(\n List.tabulate<Nat>(10, func i { if (i < 9) { i } else { i + 1 } }),\n List.tabulate<Nat>(10, func i { i }),\n Nat.equal\n ),\n M.equals(T.bool(false))\n ),\n ]\n);\n\nlet zipWith = Suite.suite(\n \"zipWith\",\n [\n Suite.test(\n \"small-list-equal-len\",\n List.zipWith<Nat, Nat, Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(10, func i { i }),\n func (i, j) { i * j }\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(10, func i { i * i}))\n )),\n Suite.test(\n \"small-list-shorter\",\n List.zipWith<Nat, Nat, Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(11, func i { i }),\n func (i, j) { i * j }\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(10, func i { i * i}))\n )),\n Suite.test(\n \"small-list-longer\",\n List.zipWith<Nat, Nat, Nat>(\n List.tabulate<Nat>(11, func i { i }),\n List.tabulate<Nat>(10, func i { i }),\n func (i, j) { i * j }\n ),\n M.equals(\n T.list(T.natTestable, List.tabulate<Nat>(10, func i { i * i}))\n )),\n Suite.test(\n \"small-list-empty-left\",\n List.zipWith<Nat, Nat, Nat>(\n null,\n List.tabulate<Nat>(10, func i { i }),\n func (i, j) { i * j }\n ),\n M.equals(\n T.list(T.natTestable, null : List.List<Nat>)\n )),\n Suite.test(\n \"small-list-empty-right\",\n List.zipWith<Nat, Nat, Nat>(\n List.tabulate<Nat>(10, func i { i }),\n null,\n func (i, j) { i * j }\n ),\n M.equals(\n T.list(T.natTestable, null : List.List<Nat>)\n )),\n Suite.test(\n \"small-list-both-empty\",\n List.zipWith<Nat, Nat, Nat>(\n null,\n null,\n func (i, j) { i * j }\n ),\n M.equals(\n T.list(T.natTestable, null : List.List<Nat>)\n )),\n ]\n);\n\nlet zip = Suite.suite(\n \"zip\",\n [\n Suite.test(\n \"small-list-equal-len\",\n List.zip<Nat, Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(10, func i { i })\n ),\n M.equals(\n T.list(T.tuple2Testable(T.natTestable,T.natTestable),\n List.tabulate<(Nat, Nat)>(10, func i { (i, i) }))\n )),\n Suite.test(\n \"small-list-shorter\",\n List.zip<Nat, Nat>(\n List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(11, func i { i })\n ),\n M.equals(\n T.list(T.tuple2Testable(T.natTestable,T.natTestable),\n List.tabulate<(Nat, Nat)>(10, func i { (i, i) }))\n )),\n Suite.test(\n \"small-list-longer\",\n List.zip<Nat, Nat>(\n List.tabulate<Nat>(11, func i { i }),\n List.tabulate<Nat>(10, func i { i })\n ),\n M.equals(\n T.list(T.tuple2Testable(T.natTestable,T.natTestable),\n List.tabulate<(Nat, Nat)>(10, func i { (i, i) }))\n )),\n Suite.test(\n \"small-list-empty-left\",\n List.zip<Nat, Nat>(\n null,\n List.tabulate<Nat>(10, func i { i })\n ),\n M.equals(\n T.list(T.tuple2Testable(T.natTestable,T.natTestable),\n null : List.List<(Nat, Nat)>)\n )),\n Suite.test(\n \"small-list-empty-right\",\n List.zip<Nat, Nat>(\n List.tabulate<Nat>(10, func i { i }),\n null\n ),\n M.equals(\n T.list(T.tuple2Testable(T.natTestable,T.natTestable),\n null : List.List<(Nat, Nat)>)\n )),\n Suite.test(\n \"small-list-both-empty\",\n List.zip<Nat, Nat>(\n null,\n null\n ),\n M.equals(\n T.list(T.tuple2Testable(T.natTestable,T.natTestable),\n null : List.List<(Nat, Nat)>)\n )),\n ]\n);\n\nlet split = Suite.suite(\n \"split\",\n [\n Suite.test(\n \"split-zero-nonempty\",\n List.split<Nat>(0,\n List.tabulate<Nat>(10, func i { i }),\n ),\n M.equals(\n T.tuple2(\n T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (null : List.List<Nat>,\n List.tabulate<Nat>(10, func i { i })))\n )),\n\n Suite.test(\n \"split-zero-empty\",\n List.split<Nat>(0,\n null\n ),\n M.equals(\n T.tuple2(\n T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (null : List.List<Nat>,\n null : List.List<Nat>))\n )),\n\n Suite.test(\n \"split-nonzero-empty\",\n List.split<Nat>(15,\n null\n ),\n M.equals(\n T.tuple2(\n T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (null : List.List<Nat>,\n null : List.List<Nat>))\n )),\n\n Suite.test(\n \"split-too-few\",\n List.split<Nat>(15,\n List.tabulate<Nat>(10, func i { i }),\n ),\n M.equals(\n T.tuple2(\n T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (List.tabulate<Nat>(10, func i { i }),\n null : List.List<Nat>\n ))\n )),\n\n Suite.test(\n \"split-too-many\",\n List.split<Nat>(10,\n List.tabulate<Nat>(15, func i { i }),\n ),\n M.equals(\n T.tuple2(\n T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (List.tabulate<Nat>(10, func i { i }),\n List.tabulate<Nat>(5, func i { 10 + i })\n ))\n )),\n\n Suite.test(\n \"split-one\",\n List.split<Nat>(1,\n List.tabulate<Nat>(15, func i { i }),\n ),\n M.equals(\n T.tuple2(\n T.listTestable(T.natTestable),\n T.listTestable(T.natTestable),\n (List.tabulate<Nat>(1, func i { i }),\n List.tabulate<Nat>(14, func i { 1 + i })\n ))\n )),\n\n ]\n);\n\nlet chunks = Suite.suite(\n \"chunks\",\n [\n Suite.test(\n \"five-even-split\",\n List.chunks<Nat>(5,\n List.tabulate<Nat>(10, func i { i }),\n ),\n M.equals(\n T.list(\n T.listTestable(T.natTestable),\n (List.tabulate<List.List<Nat>>(2, func i {\n List.tabulate<Nat>(5, func j { i * 5 + j }) })))\n )),\n Suite.test(\n \"five-remainder\",\n List.chunks<Nat>(5,\n List.tabulate<Nat>(13, func i { i }),\n ),\n M.equals(\n T.list(\n T.listTestable(T.natTestable),\n (List.tabulate<List.List<Nat>>((13+4)/5, func i {\n List.tabulate<Nat>(if (i < 13 / 5) 5 else 13 % 5, func j { i * 5 + j }) })))\n )),\n Suite.test(\n \"five-too-few\",\n List.chunks<Nat>(5,\n List.tabulate<Nat>(3, func i { i }),\n ),\n M.equals(\n T.list(\n T.listTestable(T.natTestable),\n (List.tabulate<List.List<Nat>>(1, func i {\n List.tabulate<Nat>(3, func j { i * 5 + j }) })))\n )),\n Suite.test(\n \"split-zero\",\n List.chunks<Nat>(0,\n List.tabulate<Nat>(5, func i { i }),\n ),\n M.equals(\n T.list(\n T.listTestable(T.natTestable),\n (null : List.List<List.List<Nat>>))\n )),\n ]\n);\n\n\nSuite.run(Suite.suite(\"List\", [\n mapResult,\n replicate,\n tabulate,\n append,\n isNil,\n push,\n last,\n pop,\n size,\n get,\n reverse,\n iterate,\n map,\n filter,\n partition,\n mapFilter,\n flatten,\n make,\n take,\n drop,\n foldLeft,\n foldRight,\n find,\n all,\n some,\n merge,\n compare,\n equal,\n zipWith,\n zip,\n split,\n chunks\n ]))\n\n"},"optionTest.mo":{"content":"import Option \"mo:base/Option\";\nimport Debug \"mo:base/Debug\";\n\nDebug.print(\"Option\");\n\ndo {\n Debug.print(\" apply\");\n\n do {\n Debug.print(\" null function, null value\");\n\n let actual = Option.apply<Int, Bool>(null, null);\n let expected : ?Bool = null;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (false)\n };\n case (_, _) {\n assert (true)\n }\n }\n };\n\n do {\n Debug.print(\" null function, non-null value\");\n\n let actual = Option.apply<Int, Bool>(?0, null);\n let expected : ?Bool = null;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (false)\n };\n case (_, _) {\n assert (true)\n }\n }\n };\n\n do {\n Debug.print(\" non-null function, null value\");\n\n let isEven = func(x : Int) : Bool {\n x % 2 == 0\n };\n\n let actual = Option.apply<Int, Bool>(null, ?isEven);\n let expected : ?Bool = null;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (false)\n };\n case (_, _) {\n assert (true)\n }\n }\n };\n\n do {\n Debug.print(\" non-null function, non-null value\");\n\n let isEven = func(x : Int) : Bool {\n x % 2 == 0\n };\n\n let actual = Option.apply<Int, Bool>(?0, ?isEven);\n let expected = ?true;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (actual_ == expected_)\n };\n case (_, _) {\n assert (false)\n }\n }\n };\n\n};\n\ndo {\n Debug.print(\" bind\");\n\n do {\n Debug.print(\" null value to null value\");\n\n let safeInt = func(x : Int) : ?Int {\n if (x > 9007199254740991) {\n null\n } else {\n ?x\n }\n };\n\n let actual = Option.chain<Int, Int>(null, safeInt);\n let expected : ?Int = null;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (false)\n };\n case (_, _) {\n assert (true)\n }\n }\n };\n\n do {\n Debug.print(\" non-null value to null value\");\n\n let safeInt = func(x : Int) : ?Int {\n if (x > 9007199254740991) {\n null\n } else {\n ?x\n }\n };\n\n let actual = Option.chain<Int, Int>(?9007199254740992, safeInt);\n let expected : ?Int = null;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (false)\n };\n case (_, _) {\n assert (true)\n }\n }\n };\n\n do {\n Debug.print(\" non-null value to non-null value\");\n\n let safeInt = func(x : Int) : ?Int {\n if (x > 9007199254740991) {\n null\n } else {\n ?x\n }\n };\n\n let actual = Option.chain<Int, Int>(?0, safeInt);\n let expected = ?0;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (actual_ == expected_)\n };\n case (_, _) {\n assert (false)\n }\n }\n };\n\n};\n\ndo {\n Debug.print(\" flatten\");\n\n do {\n Debug.print(\" null value\");\n\n let actual = Option.flatten<Int>(?null);\n let expected : ?Int = null;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (false)\n };\n case (_, _) {\n assert (true)\n }\n }\n };\n\n do {\n Debug.print(\" non-null value\");\n let actual = Option.flatten<Int>(??0);\n let expected = ?0;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (actual_ == expected_)\n };\n case (_, _) {\n assert (false)\n }\n }\n };\n\n};\n\ndo {\n Debug.print(\" map\");\n\n do {\n Debug.print(\" null value\");\n\n let isEven = func(x : Int) : Bool {\n x % 2 == 0\n };\n\n let actual = Option.map<Int, Bool>(null, isEven);\n let expected : ?Bool = null;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (false)\n };\n case (_, _) {\n assert (true)\n }\n }\n };\n\n do {\n Debug.print(\" non-null value\");\n\n let isEven = func(x : Int) : Bool {\n x % 2 == 0\n };\n\n let actual = Option.map<Int, Bool>(?0, isEven);\n let expected = ?true;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (actual_ == expected_)\n };\n case (_, _) {\n assert (false)\n }\n }\n };\n\n};\ndo {\n Debug.print(\" iterate\");\n\n do {\n var witness = 0;\n Option.iterate<Nat>(?(1), func(x : Nat) { witness += 1 });\n assert (witness == 1);\n Option.iterate<Nat>(null, func(x : Nat) { witness += 1 });\n assert (witness == 1)\n }\n};\n\ndo {\n Debug.print(\" make\");\n\n let actual = Option.make<Int>(0);\n let expected = ?0;\n\n switch (actual, expected) {\n case (?actual_, ?expected_) {\n assert (actual_ == expected_)\n };\n case (_, _) {\n assert (false)\n }\n }\n}\n"},"stackTest.mo":{"content":"import Stack \"mo:base/Stack\";\nimport Iter \"mo:base/Iter\";\nimport O \"mo:base/Option\";\n\ndo {\n var s = Stack.Stack<Nat>();\n for (i in Iter.range(0, 100)) {\n s.push(i)\n };\n for (i in Iter.revRange(100, 0)) {\n let x = s.pop();\n assert (O.unwrap(x) == i)\n };\n assert (s.isEmpty())\n}\n"},"trieMapTest.mo":{"content":"import Prim \"mo:⛔\";\nimport TrieMap \"mo:base/TrieMap\";\nimport Iter \"mo:base/Iter\";\nimport Hash \"mo:base/Hash\";\nimport Text \"mo:base/Text\";\nimport Nat \"mo:base/Nat\";\n\nimport Suite \"mo:matchers/Suite\";\nimport T \"mo:matchers/Testable\";\nimport M \"mo:matchers/Matchers\";\n\n// Utilities to work with Matchers\nfunc arrayTest(array : [(Nat, Nat)]) : M.Matcher<[(Nat, Nat)]> {\n M.equals<[(Nat, Nat)]>(T.array<(Nat, Nat)>(T.tuple2Testable<Nat, Nat>(T.natTestable, T.natTestable), array))\n};\n\n// Sample maps to use for testing\nlet map1 = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash);\n// resulting map is {(0, 10), (2, 12), (4, 14)}\nmap1.put(0, 10);\nmap1.put(2, 12);\nmap1.put(3, 13);\nmap1.put(4, 24);\nmap1.delete(3);\nmap1.delete(4);\nmap1.put(4, 14);\n\nlet suite = Suite.suite(\n \"TrieMap\",\n [\n Suite.test(\n \"size\",\n map1.size(),\n M.equals(T.nat(3))\n ),\n Suite.test(\n \"size empty\",\n TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash).size(),\n M.equals(T.nat(0))\n ),\n Suite.test(\n \"put\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.put(5, 15);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 10), (2, 12), (4, 14), (5, 15)])\n ),\n Suite.test(\n \"put overwrite\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.put(0, 20);\n map.put(4, 24);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 20), (2, 12), (4, 24)])\n ),\n Suite.test(\n \"put empty\",\n do {\n let map = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash);\n map.put(0, 10);\n map.put(2, 12);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 10), (2, 12)])\n ),\n Suite.test(\n \"replace old value\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.replace(5, 15)\n },\n M.equals(T.optional<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"replace new map\",\n do {\n let map = TrieMap.clone<Nat, Nat>(map1, Nat.equal, Hash.hash);\n ignore map.replace(5, 15);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 10), (2, 12), (4, 14), (5, 15)])\n ),\n Suite.test(\n \"replace overwrite old value\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.replace(0, 20)\n },\n M.equals(T.optional(T.natTestable, ?10))\n ),\n Suite.test(\n \"replace overwrite new map\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n ignore map.replace(0, 20);\n ignore map.replace(4, 24);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 20), (2, 12), (4, 24)])\n ),\n Suite.test(\n \"replace empty\",\n do {\n let map = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash);\n ignore map.replace(0, 20);\n ignore map.replace(4, 24);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 20), (4, 24)])\n ),\n Suite.test(\n \"get\",\n map1.get(4),\n M.equals(T.optional(T.natTestable, ?14))\n ),\n Suite.test(\n \"get key not present\",\n map1.get(3),\n M.equals(T.optional<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"get empty\",\n TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash).get(3),\n M.equals(T.optional<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"delete\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.delete(2);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 10), (4, 14)])\n ),\n Suite.test(\n \"delete key not present\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.delete(3);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"delete empty\",\n do {\n let map = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash);\n map.delete(3);\n Iter.toArray(map.entries())\n },\n arrayTest([])\n ),\n Suite.test(\n \"remove old value\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.remove(4)\n },\n M.equals(T.optional(T.natTestable, ?14))\n ),\n Suite.test(\n \"remove new map\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n ignore map.remove(4);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 10), (2, 12)])\n ),\n Suite.test(\n \"remove key not present old value\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n map.remove(3)\n },\n M.equals(T.optional<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"remove key not present new map\",\n do {\n let map = TrieMap.clone(map1, Nat.equal, Hash.hash);\n ignore map.remove(3);\n Iter.toArray(map.entries())\n },\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"remove empty old value\",\n do {\n let map = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash);\n map.remove(3)\n },\n M.equals(T.optional<Nat>(T.natTestable, null))\n ),\n Suite.test(\n \"remove empty new map\",\n do {\n let map = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash);\n ignore map.remove(3);\n Iter.toArray(map.entries())\n },\n arrayTest([])\n ),\n Suite.test(\n \"keys\",\n Iter.toArray(map1.keys()),\n M.equals(T.array(T.natTestable, [0, 2, 4]))\n ),\n Suite.test(\n \"keys empty\",\n Iter.toArray(TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash).keys()),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"vals\",\n Iter.toArray(map1.vals()),\n M.equals(T.array(T.natTestable, [10, 12, 14]))\n ),\n Suite.test(\n \"vals empty\",\n Iter.toArray(TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash).vals()),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"entries\",\n Iter.toArray(map1.entries()),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"entries empty\",\n Iter.toArray(TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash).entries()),\n arrayTest([])\n ),\n Suite.test(\n \"clone\",\n Iter.toArray(TrieMap.clone<Nat, Nat>(map1, Nat.equal, Hash.hash).entries()),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"clone empty\",\n Iter.toArray(\n TrieMap.clone(\n TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash),\n Nat.equal,\n Hash.hash\n ).entries()\n ),\n arrayTest([])\n ),\n Suite.test(\n \"fromEntries round trip\",\n Iter.toArray(\n TrieMap.fromEntries<Nat, Nat>(\n [(0, 10), (2, 12), (4, 14)].vals(),\n Nat.equal,\n Hash.hash\n ).entries()\n ),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"fromEntries empty round trip\",\n Iter.toArray(\n TrieMap.fromEntries<Nat, Nat>(\n [].vals(),\n Nat.equal,\n Hash.hash\n ).entries()\n ),\n arrayTest([])\n ),\n Suite.test(\n \"map\",\n Iter.toArray(\n TrieMap.map<Nat, Nat, Nat>(\n map1,\n Nat.equal,\n Hash.hash,\n Nat.add\n ).entries()\n ),\n arrayTest([(0, 10), (2, 14), (4, 18)])\n ),\n Suite.test(\n \"map empty\",\n Iter.toArray(\n TrieMap.map<Nat, Nat, Nat>(\n TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash),\n Nat.equal,\n Hash.hash,\n Nat.add\n ).entries()\n ),\n arrayTest([])\n ),\n Suite.test(\n \"mapFilter\",\n Iter.toArray(\n TrieMap.mapFilter<Nat, Nat, Nat>(\n map1,\n Nat.equal,\n Hash.hash,\n func(k, v) {\n if (k == 0) {\n null\n } else {\n ?(k + v)\n }\n }\n ).entries()\n ),\n arrayTest([(2, 14), (4, 18)])\n ),\n Suite.test(\n \"mapFilter all\",\n Iter.toArray(\n TrieMap.mapFilter<Nat, Nat, Nat>(\n map1,\n Nat.equal,\n Hash.hash,\n func _ = null\n ).entries()\n ),\n arrayTest([])\n ),\n Suite.test(\n \"mapFilter none\",\n Iter.toArray(\n TrieMap.mapFilter<Nat, Nat, Nat>(\n map1,\n Nat.equal,\n Hash.hash,\n func(k, v) = ?(k + v)\n ).entries()\n ),\n arrayTest([(0, 10), (2, 14), (4, 18)])\n ),\n Suite.test(\n \"mapFilter empty\",\n Iter.toArray(\n TrieMap.mapFilter<Nat, Nat, Nat>(\n TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash),\n Nat.equal,\n Hash.hash,\n func(k, v) = ?(k + v)\n ).entries()\n ),\n arrayTest([])\n )\n ]\n);\n\nSuite.run(suite);\n\ndebug {\n let a = TrieMap.TrieMap<Text, Nat>(Text.equal, Text.hash);\n\n assert a.size() == 0;\n ignore a.remove(\"apple\");\n assert a.size() == 0;\n\n a.put(\"apple\", 1);\n assert a.size() == 1;\n ignore a.remove(\"apple\");\n assert a.size() == 0;\n\n a.put(\"apple\", 1);\n a.put(\"banana\", 2);\n a.put(\"pear\", 3);\n a.put(\"avocado\", 4);\n a.put(\"Apple\", 11);\n a.put(\"Banana\", 22);\n a.put(\"Pear\", 33);\n a.put(\"Avocado\", 44);\n a.put(\"ApplE\", 111);\n a.put(\"BananA\", 222);\n a.put(\"PeaR\", 333);\n a.put(\"AvocadO\", 444);\n\n // need to resupply the constructor args; they are private to the object; but, should they be?\n let b = TrieMap.clone<Text, Nat>(a, Text.equal, Text.hash);\n\n // ensure clone has each key-value pair present in original\n for ((k, v) in a.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (b.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // ensure clone has each key present in original\n for (k in a.keys()) {\n switch (b.get(k)) {\n case null { assert false };\n case (?_) {}\n }\n };\n\n // ensure clone has each value present in original\n for (v in a.vals()) {\n var foundMatch = false;\n for (w in b.vals()) {\n if (v == w) { foundMatch := true }\n };\n assert foundMatch\n };\n\n // ensure original has each key-value pair present in clone\n for ((k, v) in b.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (a.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // do some more operations:\n a.put(\"apple\", 1111);\n a.put(\"banana\", 2222);\n a.delete(\"pear\");\n a.delete(\"avocado\");\n\n // check them:\n switch (a.get(\"apple\")) {\n case (?1111) {};\n case _ { assert false }\n };\n switch (a.get(\"banana\")) {\n case (?2222) {};\n case _ { assert false }\n };\n switch (a.get(\"pear\")) {\n case null {};\n case (?_) { assert false }\n };\n switch (a.get(\"avocado\")) {\n case null {};\n case (?_) { assert false }\n };\n\n // undo operations above:\n a.put(\"apple\", 1);\n a.put(\"banana\", 2);\n a.put(\"pear\", 3);\n a.put(\"avocado\", 4);\n\n // ensure clone has each key-value pair present in original\n for ((k, v) in a.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (b.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // ensure original has each key-value pair present in clone\n for ((k, v) in b.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (a.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // test fromEntries method\n let c = TrieMap.fromEntries<Text, Nat>(b.entries(), Text.equal, Text.hash);\n\n // c agrees with each entry of b\n for ((k, v) in b.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (c.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // b agrees with each entry of c\n for ((k, v) in c.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (b.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n }\n}\n"},"hashMapTest.mo":{"content":"import Prim \"mo:⛔\";\nimport H \"mo:base/HashMap\";\nimport Hash \"mo:base/Hash\";\nimport Text \"mo:base/Text\";\n\ndebug {\n let a = H.HashMap<Text, Nat>(3, Text.equal, Text.hash);\n\n a.put(\"apple\", 1);\n a.put(\"banana\", 2);\n a.put(\"pear\", 3);\n a.put(\"avocado\", 4);\n a.put(\"Apple\", 11);\n a.put(\"Banana\", 22);\n a.put(\"Pear\", 33);\n a.put(\"Avocado\", 44);\n a.put(\"ApplE\", 111);\n a.put(\"BananA\", 222);\n a.put(\"PeaR\", 333);\n a.put(\"AvocadO\", 444);\n\n // need to resupply the constructor args; they are private to the object; but, should they be?\n let b = H.clone<Text, Nat>(a, Text.equal, Text.hash);\n\n // ensure clone has each key-value pair present in original\n for ((k, v) in a.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (b.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // ensure original has each key-value pair present in clone\n for ((k, v) in b.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (a.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // ensure clone has each key present in original\n for (k in a.keys()) {\n switch (b.get(k)) {\n case null { assert false };\n case (?_) {}\n }\n };\n\n // ensure clone has each value present in original\n for (v in a.vals()) {\n var foundMatch = false;\n for (w in b.vals()) {\n if (v == w) { foundMatch := true }\n };\n assert foundMatch\n };\n\n // do some more operations:\n a.put(\"apple\", 1111);\n a.put(\"banana\", 2222);\n switch (a.remove(\"pear\")) {\n case null { assert false };\n case (?three) { assert three == 3 }\n };\n a.delete(\"avocado\");\n\n // check them:\n switch (a.get(\"apple\")) {\n case (?1111) {};\n case _ { assert false }\n };\n switch (a.get(\"banana\")) {\n case (?2222) {};\n case _ { assert false }\n };\n switch (a.get(\"pear\")) {\n case null {};\n case (?_) { assert false }\n };\n switch (a.get(\"avocado\")) {\n case null {};\n case (?_) { assert false }\n };\n\n // undo operations above:\n a.put(\"apple\", 1);\n // .. and test that replace works\n switch (a.replace(\"apple\", 666)) {\n case null { assert false };\n case (?one) {\n assert one == 1; // ...and revert\n a.put(\"apple\", 1)\n }\n };\n a.put(\"banana\", 2);\n a.put(\"pear\", 3);\n a.put(\"avocado\", 4);\n\n // ensure clone has each key-value pair present in original\n for ((k, v) in a.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (b.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // ensure original has each key-value pair present in clone\n for ((k, v) in b.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (a.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // test fromIter method\n let c = H.fromIter<Text, Nat>(b.entries(), 0, Text.equal, Text.hash);\n\n // c agrees with each entry of b\n for ((k, v) in b.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (c.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // b agrees with each entry of c\n for ((k, v) in c.entries()) {\n Prim.debugPrint(debug_show (k, v));\n switch (b.get(k)) {\n case null { assert false };\n case (?w) { assert v == w }\n }\n };\n\n // Issue #228\n let d = H.HashMap<Text, Nat>(50, Text.equal, Text.hash);\n switch (d.remove(\"test\")) {\n case null {};\n case (?_) { assert false }\n }\n}\n"},"testLenClamp.mo":{"content":"import List \"mo:base/List\";\nimport Trie \"mo:base/Trie\";\nimport Debug \"mo:base/Debug\";\n\ntype List<T> = List.List<T>;\n\n/* copied because private to Trie.mo */\nfunc lenClamp<T>(l : List<T>, max : Nat) : ?Nat {\n func rec(l : List<T>, max : Nat, i : Nat) : ?Nat {\n switch l {\n case null { ?i };\n case (?(_, t)) {\n if (i >= max) { null } else { rec(t, max, i + 1) }\n }\n }\n };\n rec(l, max, 0)\n};\n\nvar s = 0;\nvar l = List.nil<Nat>();\n\nwhile (s < 10) {\n var m = 0;\n while (m <= s + 3) {\n let o = lenClamp(l, m);\n Debug.print(debug_show ({ l = List.toArray(l); m; o }));\n assert (s == List.size(l));\n assert (if (s <= m) { o == ?s } else { o == null });\n m += 1\n };\n l := List.push(s +1, l);\n s += 1\n}\n"},"natTest.mo":{"content":"import Debug \"mo:base/Debug\";\nimport Nat \"mo:base/Nat\";\n\nDebug.print(\"Nat\");\n\ndo {\n Debug.print(\" add\");\n\n assert (Nat.add(1, Nat.add(2, 3)) == Nat.add(1, Nat.add(2, 3)));\n assert (Nat.add(0, 1) == 1);\n assert (1 == Nat.add(1, 0));\n assert (Nat.add(0, 1) == Nat.add(1, 0));\n assert (Nat.add(1, 2) == Nat.add(2, 1))\n};\n\ndo {\n Debug.print(\" toText\");\n\n assert (Nat.toText(0) == \"0\");\n assert (Nat.toText(1234) == \"1234\")\n}\n"},"trieSetTest.mo":{"content":"import Nat \"mo:base/Nat\";\nimport TrieSet \"mo:base/TrieSet\";\nimport Nat32 \"mo:base/Nat32\";\nimport Hash \"mo:base/Hash\";\nimport Suite \"mo:matchers/Suite\";\nimport M \"mo:matchers/Matchers\";\nimport T \"mo:matchers/Testable\";\n\nlet simpleTests = do {\n let set1 = TrieSet.fromArray<Nat>([1, 2, 3, 1, 2, 3, 1], Nat32.fromNat, Nat.equal);\n\n let suite = Suite.suite(\n \"TrieSet fromArray\",\n [\n Suite.test(\n \"mem\",\n TrieSet.mem<Nat>(set1, 1, 1, Nat.equal),\n M.equals(T.bool true)\n ),\n Suite.test(\n \"size\",\n TrieSet.size(set1),\n M.equals(T.nat 3)\n ),\n Suite.test(\n \"toArray\",\n TrieSet.toArray<Nat>(set1),\n M.equals(T.array<Nat>(T.natTestable, [1, 2, 3]))\n )\n ]\n );\n Suite.run(suite)\n};\n\nlet binopTests = do {\n let a = TrieSet.fromArray<Nat>([1, 3], Hash.hash, Nat.equal);\n let b = TrieSet.fromArray<Nat>([2, 3], Hash.hash, Nat.equal);\n\n let suite = Suite.suite(\n \"TrieSet -- binary operations\",\n [\n Suite.test(\n \"union\",\n TrieSet.toArray(TrieSet.union(a, b, Nat.equal)),\n M.equals(T.array<Nat>(T.natTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"intersect\",\n TrieSet.toArray(TrieSet.intersect(a, b, Nat.equal)),\n M.equals(T.array<Nat>(T.natTestable, [3]))\n ),\n Suite.test(\n \"diff\",\n TrieSet.toArray(TrieSet.diff(a, b, Nat.equal)),\n M.equals(T.array<Nat>(T.natTestable, [1]))\n )\n ]\n );\n Suite.run(suite)\n}\n"},"RBTreeTest.mo":{"content":"import Debug \"mo:base/Debug\";\nimport Nat \"mo:base/Nat\";\nimport I \"mo:base/Iter\";\nimport List \"mo:base/List\";\nimport RBT \"mo:base/RBTree\";\n\nlet sorted = [\n (1, \"reformer\"),\n (2, \"helper\"),\n (3, \"achiever\"),\n (4, \"individualist\"),\n (5, \"investigator\"),\n (6, \"loyalist\"),\n (7, \"enthusiast\"),\n (8, \"challenger\"),\n (9, \"peacemaker\")\n];\n\nlet unsort = [\n (6, \"loyalist\"),\n (3, \"achiever\"),\n (9, \"peacemaker\"),\n (1, \"reformer\"),\n (4, \"individualist\"),\n (2, \"helper\"),\n (8, \"challenger\"),\n (5, \"investigator\"),\n (7, \"enthusiast\")\n];\n\nvar t = RBT.RBTree<Nat, Text>(Nat.compare);\n\nassert RBT.size(t.share()) == 0;\n\nfor ((num, lab) in unsort.vals()) {\n Debug.print(Nat.toText num);\n Debug.print lab;\n t.put(num, lab)\n};\n\ndo {\n var i = 1;\n for ((num, lab) in t.entries()) {\n assert (num == i);\n i += 1\n }\n};\n\nassert RBT.size(t.share()) == 9;\n\ndo {\n var i = 9;\n for ((num, lab) in t.entriesRev()) {\n assert (num == i);\n i -= 1\n }\n};\n\nassert RBT.size(t.share()) == 9;\n\nt.delete(5);\n\nassert RBT.size(t.share()) == 8\n"},"arrayTest.mo":{"content":"import Array \"mo:base/Array\";\nimport Int \"mo:base/Int\";\nimport Nat \"../src/Nat\";\nimport Text \"mo:base/Text\";\nimport Result \"mo:base/Result\";\nimport Suite \"mo:matchers/Suite\";\nimport T \"mo:matchers/Testable\";\nimport M \"mo:matchers/Matchers\";\n\nlet suite = Suite.suite(\n \"Array\",\n [\n Suite.test(\n \"init\",\n Array.freeze(Array.init<Int>(3, 4)),\n M.equals(T.array<Int>(T.intTestable, [4, 4, 4]))\n ),\n Suite.test(\n \"init empty\",\n Array.freeze(Array.init<Int>(0, 4)),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"tabulate\",\n Array.tabulate<Int>(3, func(i : Nat) = i * 2),\n M.equals(T.array<Int>(T.intTestable, [0, 2, 4]))\n ),\n Suite.test(\n \"tabulate empty\",\n Array.tabulate<Int>(0, func(i : Nat) = i),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"tabulateVar\",\n Array.freeze(Array.tabulateVar<Int>(3, func(i : Nat) = i * 2)),\n M.equals(T.array<Int>(T.intTestable, [0, 2, 4]))\n ),\n Suite.test(\n \"tabulateVar empty\",\n Array.freeze(Array.tabulateVar<Int>(0, func(i : Nat) = i)),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"freeze\",\n Array.freeze<Int>([var 1, 2, 3]),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"freeze empty\",\n Array.freeze<Int>([var]),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"thaw round trip\",\n Array.freeze(Array.thaw<Int>([1, 2, 3])),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"thaw round trip empty\",\n Array.freeze(Array.thaw<Int>([])),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"equal\",\n Array.equal<Int>([1, 2, 3], [1, 2, 3], Int.equal),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"equal empty\",\n Array.equal<Int>([], [], Int.equal),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"not equal one empty\",\n Array.equal<Int>([], [2, 3], Int.equal),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"not equal different lengths\",\n Array.equal<Int>([1, 2, 3], [2, 4], Int.equal),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"not equal same lengths\",\n Array.equal<Int>([1, 2, 3], [1, 2, 4], Int.equal),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"find\",\n Array.find<Nat>([1, 9, 4, 8], func x = x == 9),\n M.equals(T.optional(T.natTestable, ?9))\n ),\n Suite.test(\n \"find fail\",\n Array.find<Nat>([1, 9, 4, 8], func _ = false),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"find empty\",\n Array.find<Nat>([], func _ = true),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"append\",\n Array.append<Int>([1, 2, 3], [4, 5, 6]),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3, 4, 5, 6]))\n ),\n Suite.test(\n \"append first empty\",\n Array.append<Int>([], [4, 5, 6]),\n M.equals(T.array<Int>(T.intTestable, [4, 5, 6]))\n ),\n Suite.test(\n \"append second empty\",\n Array.append<Int>([1, 2, 3], []),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"append both empty\",\n Array.append<Int>([], []),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"sort\",\n Array.sort([2, 3, 1], Nat.compare),\n M.equals(T.array<Nat>(T.natTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"sort empty array\",\n Array.sort([], Nat.compare),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"sort already sorted\",\n Array.sort([1, 2, 3, 4, 5], Nat.compare),\n M.equals(T.array<Nat>(T.natTestable, [1, 2, 3, 4, 5]))\n ),\n Suite.test(\n \"sort repeated elements\",\n Array.sort([2, 2, 2, 2, 2], Nat.compare),\n M.equals(T.array<Nat>(T.natTestable, [2, 2, 2, 2, 2]))\n ),\n Suite.test(\n \"sortInPlace\",\n do {\n let array = [var 2, 3, 1];\n Array.sortInPlace(array, Nat.compare);\n Array.freeze(array)\n },\n M.equals(T.array<Nat>(T.natTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"sortInPlace empty\",\n do {\n let array = [var];\n Array.sortInPlace(array, Nat.compare);\n Array.freeze(array)\n },\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"sortInPlace already sorted\",\n do {\n let array = [var 1, 2, 3, 4, 5];\n Array.sortInPlace(array, Nat.compare);\n Array.freeze(array)\n },\n M.equals(T.array<Nat>(T.natTestable, [1, 2, 3, 4, 5]))\n ),\n Suite.test(\n \"sortInPlace repeated elements\",\n do {\n let array = [var 2, 2, 2, 2, 2];\n Array.sortInPlace(array, Nat.compare);\n Array.freeze(array)\n },\n M.equals(T.array<Nat>(T.natTestable, [2, 2, 2, 2, 2]))\n ),\n Suite.test(\n \"reverse\",\n Array.reverse<Nat>([0, 1, 2, 2, 3]),\n M.equals(T.array<Nat>(T.natTestable, [3, 2, 2, 1, 0]))\n ),\n Suite.test(\n \"reverse empty\",\n Array.reverse<Nat>([]),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"reverse singleton\",\n Array.reverse<Nat>([0]),\n M.equals(T.array<Nat>(T.natTestable, [0]))\n ),\n Suite.test(\n \"map\",\n Array.map<Nat, Bool>([1, 2, 3], func x = x % 2 == 0),\n M.equals(T.array<Bool>(T.boolTestable, [false, true, false]))\n ),\n Suite.test(\n \"map empty\",\n Array.map<Nat, Bool>([], func x = x % 2 == 0),\n M.equals(T.array<Bool>(T.boolTestable, []))\n ),\n Suite.test(\n \"filter\",\n Array.filter<Nat>([1, 2, 3, 4, 5, 6], func x = x % 2 == 0),\n M.equals(T.array<Nat>(T.natTestable, [2, 4, 6]))\n ),\n Suite.test(\n \"filter empty\",\n Array.filter<Nat>([], func x = x % 2 == 0),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"mapEntries\",\n Array.mapEntries<Nat, Nat>([1, 2, 3], func(x, i) = x + i),\n M.equals(T.array<Nat>(T.natTestable, [1, 3, 5]))\n ),\n Suite.test(\n \"mapEntries empty\",\n Array.mapEntries<Nat, Nat>([], func(x, i) = x + i),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"mapFilter\",\n Array.mapFilter<Nat, Nat>([1, 2, 3, 4, 5, 6], func x { if (x % 2 == 0) ?x else null }),\n M.equals(T.array<Nat>(T.natTestable, [2, 4, 6]))\n ),\n Suite.test(\n \"mapFilter keep all\",\n Array.mapFilter<Nat, Nat>([1, 2, 3], func x = ?x),\n M.equals(T.array<Nat>(T.natTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"mapFilter keep none\",\n Array.mapFilter<Nat, Nat>([1, 2, 3], func _ = null),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"mapFilter empty\",\n Array.mapFilter<Nat, Nat>([], func x { if (x % 2 == 0) ?x else null }),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n Suite.test(\n \"mapResult\",\n Array.mapResult<Int, Nat, Text>(\n [1, 2, 3],\n func x { if (x >= 0) { #ok(Int.abs x) } else { #err \"error message\" } }\n ),\n M.equals(T.result<[Nat], Text>(T.arrayTestable(T.natTestable), T.textTestable, #ok([1, 2, 3])))\n ),\n Suite.test(\n \"mapResult fail first\",\n Array.mapResult<Int, Nat, Text>(\n [-1, 2, 3],\n func x { if (x >= 0) { #ok(Int.abs x) } else { #err \"error message\" } }\n ),\n M.equals(T.result<[Nat], Text>(T.arrayTestable(T.natTestable), T.textTestable, #err \"error message\"))\n ),\n Suite.test(\n \"mapResult fail last\",\n Array.mapResult<Int, Nat, Text>(\n [1, 2, -3],\n func x { if (x >= 0) { #ok(Int.abs x) } else { #err \"error message\" } }\n ),\n M.equals(T.result<[Nat], Text>(T.arrayTestable(T.natTestable), T.textTestable, #err \"error message\"))\n ),\n Suite.test(\n \"mapResult empty\",\n Array.mapResult<Nat, Nat, Text>(\n [],\n func x = #ok x\n ),\n M.equals(T.result<[Nat], Text>(T.arrayTestable(T.natTestable), T.textTestable, #ok([])))\n ),\n Suite.test(\n \"chain\",\n Array.chain<Int, Int>([0, 1, 2], func x = [x, -x]),\n M.equals(T.array<Int>(T.intTestable, [0, 0, 1, -1, 2, -2]))\n ),\n Suite.test(\n \"chain empty\",\n Array.chain<Int, Int>([], func x = [x, -x]),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"foldLeft\",\n Array.foldLeft<Text, Text>([\"a\", \"b\", \"c\"], \"\", Text.concat),\n M.equals(T.text(\"abc\"))\n ),\n Suite.test(\n \"foldLeft empty\",\n Array.foldLeft<Text, Text>([], \"base\", Text.concat),\n M.equals(T.text(\"base\"))\n ),\n Suite.test(\n \"foldRight\",\n Array.foldRight<Text, Text>([\"a\", \"b\", \"c\"], \"\", func(x, acc) = acc # x),\n M.equals(T.text(\"cba\"))\n ),\n Suite.test(\n \"foldRight empty\",\n Array.foldRight<Text, Text>([], \"base\", Text.concat),\n M.equals(T.text(\"base\"))\n ),\n Suite.test(\n \"flatten\",\n Array.flatten<Int>([[1, 2, 3], [], [1]]),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3, 1]))\n ),\n Suite.test(\n \"flatten empty start\",\n Array.flatten<Int>([[], [1, 2, 3], [], [1]]),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3, 1]))\n ),\n Suite.test(\n \"flatten empty end\",\n Array.flatten<Int>([[1, 2, 3], [], [1], []]),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3, 1]))\n ),\n Suite.test(\n \"flatten singleton\",\n Array.flatten<Int>([[1, 2, 3]]),\n M.equals(T.array<Int>(T.intTestable, [1, 2, 3]))\n ),\n Suite.test(\n \"flatten empty\",\n Array.flatten<Int>([[]]),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"flatten empty\",\n Array.flatten<Int>([]),\n M.equals(T.array<Int>(T.intTestable, []))\n ),\n Suite.test(\n \"make\",\n Array.make<Int>(0),\n M.equals(T.array<Int>(T.intTestable, [0]))\n ),\n Suite.test(\n \"vals\",\n do {\n var sum = 0;\n for (x in Array.vals([1, 2, 3])) {\n sum += x\n };\n sum\n },\n M.equals(T.nat(6))\n ),\n Suite.test(\n \"vals empty\",\n do {\n var sum = 0;\n for (x in Array.vals([])) {\n sum += x\n };\n sum\n },\n M.equals(T.nat(0))\n ),\n Suite.test(\n \"keys\",\n do {\n var sum = 0;\n for (x in Array.keys([1, 2, 3])) {\n sum += x\n };\n sum\n },\n M.equals(T.nat(3))\n ),\n Suite.test(\n \"keys empty\",\n do {\n var sum = 0;\n for (x in Array.keys([])) {\n sum += x\n };\n sum\n },\n M.equals(T.nat(0))\n )\n ]\n);\n\nSuite.run(suite)\n"},"resultTest.mo":{"content":"import Result \"mo:base/Result\";\nimport Int \"mo:base/Int\";\nimport Array \"mo:base/Array\";\nimport List \"mo:base/List\";\n\nimport Suite \"mo:matchers/Suite\";\nimport M \"mo:matchers/Matchers\";\nimport T \"mo:matchers/Testable\";\n\nfunc makeNatural(x : Int) : Result.Result<Nat, Text> = if (x >= 0) {\n #ok(Int.abs(x))\n} else { #err(Int.toText(x) # \" is not a natural number.\") };\n\nfunc largerThan10(x : Nat) : Result.Result<Nat, Text> = if (x > 10) { #ok(x) } else {\n #err(Int.toText(x) # \" is not larger than 10.\")\n};\n\nlet chain = Suite.suite(\n \"chain\",\n [\n Suite.test(\n \"ok -> ok\",\n Result.chain<Nat, Nat, Text>(makeNatural(11), largerThan10),\n M.equals(T.result<Nat, Text>(T.natTestable, T.textTestable, #ok(11)))\n ),\n Suite.test(\n \"ok -> err\",\n Result.chain<Nat, Nat, Text>(makeNatural(5), largerThan10),\n M.equals(T.result<Nat, Text>(T.natTestable, T.textTestable, #err(\"5 is not larger than 10.\")))\n ),\n Suite.test(\n \"err\",\n Result.chain<Nat, Nat, Text>(makeNatural(-5), largerThan10),\n M.equals(T.result<Nat, Text>(T.natTestable, T.textTestable, #err(\"-5 is not a natural number.\")))\n )\n ]\n);\n\nlet flatten = Suite.suite(\n \"flatten\",\n [\n Suite.test(\n \"ok -> ok\",\n Result.flatten<Nat, Text>(#ok(#ok(10))),\n M.equals(T.result<Nat, Text>(T.natTestable, T.textTestable, #ok(10)))\n ),\n Suite.test(\n \"err\",\n Result.flatten<Nat, Text>(#err(\"wrong\")),\n M.equals(T.result<Nat, Text>(T.natTestable, T.textTestable, #err(\"wrong\")))\n ),\n Suite.test(\n \"ok -> err\",\n Result.flatten<Nat, Text>(#ok(#err(\"wrong\"))),\n M.equals(T.result<Nat, Text>(T.natTestable, T.textTestable, #err(\"wrong\")))\n )\n ]\n);\n\nlet iterate = Suite.suite(\n \"iterate\",\n do {\n var tests : [Suite.Suite] = [];\n var counter : Nat = 0;\n Result.iterate(makeNatural(5), func(x : Nat) { counter += x });\n tests := Array.append(tests, [Suite.test(\"ok\", counter, M.equals(T.nat(5)))]);\n Result.iterate(makeNatural(-10), func(x : Nat) { counter += x });\n tests := Array.append(tests, [Suite.test(\"err\", counter, M.equals(T.nat(5)))]);\n tests\n }\n);\n\nlet suite = Suite.suite(\n \"Result\",\n [\n chain,\n flatten,\n iterate\n ]\n);\n\nSuite.run(suite)\n"},"trieTest.mo":{"content":"import Trie \"mo:base/Trie\";\nimport List \"mo:base/List\";\nimport Nat \"mo:base/Nat\";\nimport Hash \"mo:base/Hash\";\nimport Option \"mo:base/Option\";\nimport Iter \"mo:base/Iter\";\nimport Text \"mo:base/Text\";\nimport Debug \"mo:base/Debug\";\nimport Array \"mo:base/Array\";\n\nimport Suite \"mo:matchers/Suite\";\nimport T \"mo:matchers/Testable\";\nimport M \"mo:matchers/Matchers\";\n\nlet test = Suite;\n\n// Utilities to massage types between Trie and Matchers\nfunc prettyArray(trie : Trie.Trie<Nat, Nat>) : [(Nat, Nat)] {\n Trie.toArray<Nat, Nat, (Nat, Nat)>(trie, func kv = kv)\n};\n\nfunc prettyArray2D(trie2D1 : Trie.Trie2D<Nat, Nat, Nat>) : [((Nat, Nat), Nat)] {\n Array.flatten(\n Trie.toArray<Nat, Trie.Trie<Nat, Nat>, [((Nat, Nat), Nat)]>(\n trie2D1,\n func(k1, trie) {\n let innerArray = prettyArray trie;\n Array.map<(Nat, Nat), ((Nat, Nat), Nat)>(innerArray, func(k2, v) = ((k1, k2), v))\n }\n )\n )\n};\n\nfunc prettyArray3D(trie3D : Trie.Trie3D<Nat, Nat, Nat, Nat>) : [((Nat, Nat, Nat), Nat)] {\n Array.flatten(\n Trie.toArray<Nat, Trie.Trie<Nat, Trie.Trie<Nat, Nat>>, [((Nat, Nat, Nat), Nat)]>(\n trie3D,\n func(k1, trie2D1) {\n let innerArray = prettyArray2D trie2D1;\n Array.map<((Nat, Nat), Nat), ((Nat, Nat, Nat), Nat)>(innerArray, func((k2, k3), v) = ((k1, k2, k3), v))\n }\n )\n )\n};\n\nfunc arrayTest(array : [(Nat, Nat)]) : M.Matcher<[(Nat, Nat)]> {\n M.equals<[(Nat, Nat)]>(T.array<(Nat, Nat)>(T.tuple2Testable<Nat, Nat>(T.natTestable, T.natTestable), array))\n};\n\nfunc arrayTest2D(array : [((Nat, Nat), Nat)]) : M.Matcher<[((Nat, Nat), Nat)]> {\n M.equals<[((Nat, Nat), Nat)]>(\n T.array<((Nat, Nat), Nat)>(\n T.tuple2Testable<(Nat, Nat), Nat>(\n T.tuple2Testable<Nat, Nat>(T.natTestable, T.natTestable),\n T.natTestable\n ),\n array\n )\n )\n};\n\nfunc arrayTest3D(array : [((Nat, Nat, Nat), Nat)]) : M.Matcher<[((Nat, Nat, Nat), Nat)]> {\n let tuple3Testable : T.Testable<(Nat, Nat, Nat)> = {\n display = func t { debug_show t };\n equals = func(t1, t2) { t1 == t2 }\n };\n\n M.equals<[((Nat, Nat, Nat), Nat)]>(\n T.array<((Nat, Nat, Nat), Nat)>(\n T.tuple2Testable<(Nat, Nat, Nat), Nat>(\n tuple3Testable,\n T.natTestable\n ),\n array\n )\n )\n};\n\nfunc natKey(nat : Nat) : Trie.Key<Nat> { { hash = Hash.hash(nat); key = nat } };\nlet natKeyTestable : T.Testable<Trie.Key<Nat>> = {\n display = func k { debug_show k.key };\n equals = func(k1, k2) { k1 == k2 }\n};\n\n// Sample tries for testing\n// FIXME tweak the keys to force collisions here\nvar trie1 = Trie.empty<Nat, Nat>();\ntrie1 := Trie.put<Nat, Nat>(trie1, natKey(0), Nat.equal, 10).0;\ntrie1 := Trie.put<Nat, Nat>(trie1, natKey(2), Nat.equal, 12).0;\ntrie1 := Trie.put<Nat, Nat>(trie1, natKey(4), Nat.equal, 14).0;\n\nvar trie2 = Trie.empty<Nat, Nat>();\ntrie2 := Trie.put<Nat, Nat>(trie2, natKey(1), Nat.equal, 11).0;\ntrie2 := Trie.put<Nat, Nat>(trie2, natKey(3), Nat.equal, 13).0;\n\nvar trie3 = Trie.empty<Nat, Nat>();\ntrie3 := Trie.put<Nat, Nat>(trie3, natKey(1), Nat.equal, 21).0;\ntrie3 := Trie.put<Nat, Nat>(trie3, natKey(2), Nat.equal, 22).0;\n\n// Sample 2D trie for testing\nvar trie2D1 = Trie.empty<Nat, Trie.Trie<Nat, Nat>>();\ntrie2D1 := Trie.put2D<Nat, Nat, Nat>(trie2D1, natKey(0), Nat.equal, natKey(10), Nat.equal, 100);\ntrie2D1 := Trie.put2D<Nat, Nat, Nat>(trie2D1, natKey(2), Nat.equal, natKey(12), Nat.equal, 102);\ntrie2D1 := Trie.put2D<Nat, Nat, Nat>(trie2D1, natKey(4), Nat.equal, natKey(14), Nat.equal, 104);\n\nvar trie2D2 = Trie.empty<Nat, Trie.Trie<Nat, Nat>>();\ntrie2D2 := Trie.put2D<Nat, Nat, Nat>(trie2D2, natKey(1), Nat.equal, natKey(11), Nat.equal, 101);\ntrie2D2 := Trie.put2D<Nat, Nat, Nat>(trie2D2, natKey(1), Nat.equal, natKey(21), Nat.equal, 201);\ntrie2D2 := Trie.put2D<Nat, Nat, Nat>(trie2D2, natKey(2), Nat.equal, natKey(12), Nat.equal, 102);\ntrie2D2 := Trie.put2D<Nat, Nat, Nat>(trie2D2, natKey(3), Nat.equal, natKey(13), Nat.equal, 103);\ntrie2D2 := Trie.put2D<Nat, Nat, Nat>(trie2D2, natKey(3), Nat.equal, natKey(23), Nat.equal, 203);\ntrie2D2 := Trie.put2D<Nat, Nat, Nat>(trie2D2, natKey(3), Nat.equal, natKey(33), Nat.equal, 303);\n\n// Sample 3D trie for testing\nvar trie3D = Trie.empty<Nat, Trie.Trie<Nat, Trie.Trie<Nat, Nat>>>();\ntrie3D := Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(0), Nat.equal, natKey(10), Nat.equal, natKey(100), Nat.equal, 1000);\ntrie3D := Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(2), Nat.equal, natKey(12), Nat.equal, natKey(102), Nat.equal, 1002);\ntrie3D := Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(4), Nat.equal, natKey(14), Nat.equal, natKey(104), Nat.equal, 1004);\n\n// Matchers tests\nlet suite = Suite.suite(\n \"Trie\",\n [\n Suite.test(\n \"empty trie size 0\",\n Trie.size(Trie.empty()),\n M.equals(T.nat(0))\n ),\n Suite.test(\n \"empty trie array roundtrip\",\n prettyArray(Trie.empty()),\n arrayTest([])\n ),\n Suite.test(\n \"put 1\",\n prettyArray(Trie.put<Nat, Nat>(Trie.empty(), natKey(0), Nat.equal, 10).0),\n arrayTest([(0, 10)])\n ),\n Suite.test(\n \"put get 1\",\n Trie.get(Trie.put<Nat, Nat>(Trie.empty(), natKey(0), Nat.equal, 10).0, natKey(0), Nat.equal),\n M.equals(T.optional(T.natTestable, ?10))\n ),\n Suite.test(\n \"put find 1\",\n Trie.find(Trie.put<Nat, Nat>(Trie.empty(), natKey(0), Nat.equal, 10).0, natKey(0), Nat.equal),\n M.equals(T.optional(T.natTestable, ?10))\n ),\n Suite.test(\n \"merge\",\n prettyArray(Trie.merge(trie1, trie3, Nat.equal)),\n arrayTest([(0, 10), (4, 14), (1, 21), (2, 12)])\n ),\n Suite.test(\n \"merge with empty\",\n prettyArray(Trie.merge(trie1, Trie.empty(), Nat.equal)),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"merge two empties\",\n prettyArray(Trie.merge(Trie.empty(), Trie.empty(), Nat.equal)),\n arrayTest([])\n ),\n Suite.test(\n \"merge disjoint\",\n prettyArray(Trie.mergeDisjoint(trie1, trie2, Nat.equal)),\n arrayTest([(0, 10), (2, 12), (4, 14), (1, 11), (3, 13)])\n ),\n Suite.test(\n \"merge disjoint one empty\",\n prettyArray(Trie.mergeDisjoint(trie1, Trie.empty(), Nat.equal)),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"merge disjoint two empties\",\n prettyArray(Trie.mergeDisjoint(Trie.empty(), Trie.empty(), Nat.equal)),\n arrayTest([])\n ),\n Suite.test(\n \"diff\",\n prettyArray(Trie.diff(trie1, trie3, Nat.equal)),\n arrayTest([(0, 10), (4, 14)])\n ),\n Suite.test(\n \"diff non-commutative\",\n prettyArray(Trie.diff(trie3, trie1, Nat.equal)),\n arrayTest([(1, 21)])\n ),\n Suite.test(\n \"diff empty right\",\n prettyArray(Trie.diff(trie1, Trie.empty(), Nat.equal)),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"diff empty left\",\n prettyArray(Trie.diff(Trie.empty(), trie1, Nat.equal)),\n arrayTest([])\n ),\n Suite.test(\n \"disj\",\n prettyArray(\n Trie.disj<Nat, Nat, Nat, Nat>(\n trie1,\n trie3,\n Nat.equal,\n func(v1, v2) {\n switch (v1, v2) {\n case (?v1, ?v2) v1 + v2; // add values to combine\n case (?v1, null) v1;\n case (null, ?v2) v2;\n case (null, null) Debug.trap \"unreachable in disj\"\n }\n }\n )\n ),\n arrayTest([(0, 10), (4, 14), (1, 21), (2, 34)])\n ),\n Suite.test(\n \"disj with empty first\",\n prettyArray(\n Trie.disj<Nat, Nat, Nat, Nat>(\n Trie.empty(),\n trie1,\n Nat.equal,\n func(v1, v2) {\n switch (v1, v2) {\n case (?v1, ?v2) v1 + v2; // add values to combine\n case (?v1, null) v1;\n case (null, ?v2) v2;\n case (null, null) Debug.trap \"unreachable in disj\"\n }\n }\n )\n ),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"disj with empty second\",\n prettyArray(\n Trie.disj<Nat, Nat, Nat, Nat>(\n trie1,\n Trie.empty(),\n Nat.equal,\n func(v1, v2) {\n switch (v1, v2) {\n case (?v1, ?v2) v1 + v2; // add values to combine\n case (?v1, null) v1;\n case (null, ?v2) v2;\n case (null, null) Debug.trap \"unreachable in disj\"\n }\n }\n )\n ),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"disj two empties\",\n prettyArray(\n Trie.disj<Nat, Nat, Nat, Nat>(\n Trie.empty(),\n Trie.empty(),\n Nat.equal,\n func(v1, v2) {\n switch (v1, v2) {\n case (?v1, ?v2) v1 + v2; // add values to combine\n case (?v1, null) v1;\n case (null, ?v2) v2;\n case (null, null) Debug.trap \"unreachable in disj\"\n }\n }\n )\n ),\n arrayTest([])\n ),\n Suite.test(\n \"join\",\n prettyArray(\n Trie.join<Nat, Nat, Nat, Nat>(trie1, trie3, Nat.equal, Nat.add)\n ),\n arrayTest([(2, 34)])\n ),\n Suite.test(\n \"join with empty first\",\n prettyArray(\n Trie.join<Nat, Nat, Nat, Nat>(Trie.empty(), trie1, Nat.equal, Nat.add)\n ),\n arrayTest([])\n ),\n Suite.test(\n \"join with empty second\",\n prettyArray(\n Trie.join<Nat, Nat, Nat, Nat>(trie1, Trie.empty(), Nat.equal, Nat.add)\n ),\n arrayTest([])\n ),\n Suite.test(\n \"join with two empties\",\n prettyArray(\n Trie.join<Nat, Nat, Nat, Nat>(Trie.empty(), Trie.empty(), Nat.equal, Nat.add)\n ),\n arrayTest([])\n ),\n Suite.test(\n \"foldUp\",\n Trie.foldUp<Nat, Nat, Nat>(trie1, Nat.mul, Nat.add, 1),\n M.equals(T.nat(2520))\n ), // 1 * (0 + 10) * (2 + 12) * (4 + 14)\n Suite.test(\n \"foldUp empty\",\n Trie.foldUp<Nat, Nat, Nat>(Trie.empty(), Nat.mul, Nat.add, 1),\n M.equals(T.nat(1))\n ),\n Suite.test(\n \"prod\",\n prettyArray(Trie.prod<Nat, Nat, Nat, Nat, Nat, Nat>(trie1, trie3, func(k1, v1, k2, v2) = ?(natKey(k1 + k2), v1 + v2), Nat.equal)),\n arrayTest([(1, 31), (2, 32), (3, 33), (4, 34), (5, 35), (6, 36)])\n ),\n Suite.test(\n \"prod first empty\",\n prettyArray(Trie.prod<Nat, Nat, Nat, Nat, Nat, Nat>(Trie.empty(), trie3, func(k1, v1, k2, v2) = ?(natKey(k1 + k2), v1 + v2), Nat.equal)),\n arrayTest([])\n ),\n Suite.test(\n \"prod second empty\",\n prettyArray(Trie.prod<Nat, Nat, Nat, Nat, Nat, Nat>(trie1, Trie.empty(), func(k1, v1, k2, v2) = ?(natKey(k1 + k2), v1 + v2), Nat.equal)),\n arrayTest([])\n ),\n Suite.test(\n \"prod both empty\",\n prettyArray(Trie.prod<Nat, Nat, Nat, Nat, Nat, Nat>(Trie.empty(), Trie.empty(), func(k1, v1, k2, v2) = ?(natKey(k1 + k2), v1 + v2), Nat.equal)),\n arrayTest([])\n ),\n Suite.test(\n \"iter\",\n Iter.toArray(Trie.iter(trie1)),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"iter empty\",\n Iter.toArray(Trie.iter(Trie.empty())),\n arrayTest([])\n ),\n Suite.test(\n \"fold\",\n Trie.fold<Nat, Nat, Nat>(trie1, func(k, v, acc) = k + v + acc, 0),\n M.equals(T.nat(42))\n ), // 0 + 10 + 2 + 12 + 4 + 14\n Suite.test(\n \"fold empty\",\n Trie.fold<Nat, Nat, Nat>(Trie.empty(), func(k, v, acc) = k + v + acc, 0),\n M.equals(T.nat(0))\n ),\n Suite.test(\n \"some true\",\n Trie.some<Nat, Nat>(trie1, func(k, v) = k * v == 0),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"some false\",\n Trie.some<Nat, Nat>(trie1, func(k, _) = k % 2 != 0),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"some empty\",\n Trie.some<Nat, Nat>(Trie.empty(), func _ = true),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"all true\",\n Trie.all<Nat, Nat>(trie1, func(k, _) = k % 2 == 0),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"all false\",\n Trie.all<Nat, Nat>(trie1, func(k, v) = k * v == 0),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"all empty\",\n Trie.all<Nat, Nat>(Trie.empty(), func _ = false),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"nth\",\n Trie.nth<Nat, Nat>(trie1, 1),\n M.equals(\n T.optional(\n T.tuple2Testable(\n natKeyTestable,\n T.natTestable\n ),\n ?(natKey(2), 12)\n )\n )\n ),\n Suite.test(\n \"nth OOB\",\n Trie.nth<Nat, Nat>(trie1, 3),\n M.equals(\n T.optional(\n T.tuple2Testable(\n natKeyTestable,\n T.natTestable\n ),\n null : ?(Trie.Key<Nat>, Nat)\n )\n )\n ),\n Suite.test(\n \"nth empty\",\n Trie.nth<Nat, Nat>(Trie.empty(), 0),\n M.equals(\n T.optional(\n T.tuple2Testable(\n natKeyTestable,\n T.natTestable\n ),\n null : ?(Trie.Key<Nat>, Nat)\n )\n )\n ),\n Suite.test(\n \"isEmpty false\",\n Trie.isEmpty<Nat, Nat>(trie1),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"isEmpty true\",\n Trie.isEmpty<Nat, Nat>(Trie.empty()),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"isEmpty put remove\",\n Trie.isEmpty<Nat, Nat>(\n Trie.remove<Nat, Nat>(Trie.put<Nat, Nat>(Trie.empty(), natKey(0), Nat.equal, 10).0, natKey(0), Nat.equal).0\n ),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"filter\",\n prettyArray(Trie.filter<Nat, Nat>(trie1, func(k, v) = k * v == 0)),\n arrayTest([(0, 10)])\n ),\n Suite.test(\n \"filter all\",\n prettyArray(Trie.filter<Nat, Nat>(trie1, func _ = false)),\n arrayTest([])\n ),\n Suite.test(\n \"filter none\",\n prettyArray(Trie.filter<Nat, Nat>(trie1, func _ = true)),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"mapFilter\",\n prettyArray(Trie.mapFilter<Nat, Nat, Nat>(trie1, func(k, v) = if (k * v != 0) { ?(k * v) } else { null })),\n arrayTest([(2, 24), (4, 56)])\n ),\n Suite.test(\n \"mapFilter all\",\n prettyArray(Trie.mapFilter<Nat, Nat, Nat>(trie1, func _ = null)),\n arrayTest([])\n ),\n Suite.test(\n \"mapFilter none\",\n prettyArray(Trie.mapFilter<Nat, Nat, Nat>(trie1, func(k, v) = ?v)),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"equalStructure reflexivity\",\n Trie.equalStructure<Nat, Nat>(trie1, trie1, Nat.equal, Nat.equal),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"equalStructure not equal maps\",\n Trie.equalStructure<Nat, Nat>(trie1, trie2, Nat.equal, Nat.equal),\n M.equals(T.bool(false))\n ),\n // FIXME add case for maps that are equivalent (map-wise) but structually non-equal\n Suite.test(\n \"equalStructure first empty\",\n Trie.equalStructure<Nat, Nat>(Trie.empty(), trie2, Nat.equal, Nat.equal),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"equalStructure second empty\",\n Trie.equalStructure<Nat, Nat>(trie1, Trie.empty(), Nat.equal, Nat.equal),\n M.equals(T.bool(false))\n ),\n Suite.test(\n \"equalStructure both empty\",\n Trie.equalStructure<Nat, Nat>(Trie.empty(), Trie.empty(), Nat.equal, Nat.equal),\n M.equals(T.bool(true))\n ),\n Suite.test(\n \"replaceThen success old value\",\n Trie.replaceThen<Nat, Nat, Nat>(\n trie1,\n natKey(0),\n Nat.equal,\n 100,\n func(newTrie, oldV) = oldV,\n func _ = Debug.trap \"unreachable\"\n ),\n M.equals(T.nat(10))\n ),\n Suite.test(\n \"replaceThen success new trie\",\n prettyArray(\n Trie.replaceThen<Nat, Nat, Trie.Trie<Nat, Nat>>(\n trie1,\n natKey(0),\n Nat.equal,\n 100,\n func(newTrie, oldV) = newTrie,\n func _ = Debug.trap \"unreachable\"\n )\n ),\n arrayTest([(0, 100), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"replaceThen failure\",\n Trie.replaceThen<Nat, Nat, Nat>(\n trie1,\n natKey(3),\n Nat.equal,\n 13,\n func _ = Debug.trap \"unreachable\",\n func() = 99\n ),\n M.equals(T.nat(99))\n ),\n Suite.test(\n \"replaceThen empty\",\n Trie.replaceThen<Nat, Nat, Nat>(\n Trie.empty(),\n natKey(0),\n Nat.equal,\n 100,\n func _ = Debug.trap \"unreachable\",\n func() = 99\n ),\n M.equals(T.nat(99))\n ),\n Suite.test(\n \"putFresh success\",\n prettyArray(Trie.putFresh<Nat, Nat>(trie1, natKey(6), Nat.equal, 16)),\n arrayTest([(0, 10), (2, 12), (4, 14), (6, 16)])\n ),\n Suite.test(\n \"putFresh empty\",\n prettyArray(Trie.putFresh<Nat, Nat>(Trie.empty(), natKey(6), Nat.equal, 16)),\n arrayTest([(6, 16)])\n ),\n Suite.test(\n \"put2D\",\n prettyArray2D(Trie.put2D<Nat, Nat, Nat>(trie2D1, natKey(1), Nat.equal, natKey(11), Nat.equal, 101)),\n arrayTest2D([((0, 10), 100), ((2, 12), 102), ((4, 14), 104), ((1, 11), 101)])\n ),\n Suite.test(\n \"put2D overlapping k1\",\n prettyArray2D(Trie.put2D<Nat, Nat, Nat>(trie2D1, natKey(0), Nat.equal, natKey(11), Nat.equal, 101)),\n arrayTest2D([((0, 10), 100), ((0, 11), 101), ((2, 12), 102), ((4, 14), 104)])\n ),\n Suite.test(\n \"put2D overlapping k2\",\n prettyArray2D(Trie.put2D<Nat, Nat, Nat>(trie2D1, natKey(1), Nat.equal, natKey(10), Nat.equal, 101)),\n arrayTest2D([((0, 10), 100), ((2, 12), 102), ((4, 14), 104), ((1, 10), 101)])\n ),\n Suite.test(\n \"put2D overlapping both\",\n prettyArray2D(Trie.put2D<Nat, Nat, Nat>(trie2D1, natKey(0), Nat.equal, natKey(10), Nat.equal, 1001)),\n arrayTest2D([((0, 10), 1001), ((2, 12), 102), ((4, 14), 104)])\n ),\n Suite.test(\n \"put2D empty\",\n prettyArray2D(Trie.put2D<Nat, Nat, Nat>(Trie.empty(), natKey(0), Nat.equal, natKey(10), Nat.equal, 100)),\n arrayTest2D([((0, 10), 100)])\n ),\n Suite.test(\n \"put3D\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(1), Nat.equal, natKey(11), Nat.equal, natKey(101), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1000), ((2, 12, 102), 1002), ((4, 14, 104), 1004), ((1, 11, 101), 1001)])\n ),\n Suite.test(\n \"put3D overlapping k1\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(0), Nat.equal, natKey(11), Nat.equal, natKey(101), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1000), ((0, 11, 101), 1001), ((2, 12, 102), 1002), ((4, 14, 104), 1004)])\n ),\n Suite.test(\n \"put3D overlapping k2\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(1), Nat.equal, natKey(12), Nat.equal, natKey(101), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1000), ((2, 12, 102), 1002), ((4, 14, 104), 1004), ((1, 12, 101), 1001)])\n ),\n Suite.test(\n \"put3D overlapping k3\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(1), Nat.equal, natKey(11), Nat.equal, natKey(102), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1000), ((2, 12, 102), 1002), ((4, 14, 104), 1004), ((1, 11, 102), 1001)])\n ),\n Suite.test(\n \"put3D overlapping k1 and k2\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(0), Nat.equal, natKey(10), Nat.equal, natKey(101), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1000), ((0, 10, 101), 1001), ((2, 12, 102), 1002), ((4, 14, 104), 1004)])\n ),\n Suite.test(\n \"put3D overlapping k1 and k3\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(0), Nat.equal, natKey(11), Nat.equal, natKey(100), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1000), ((0, 11, 100), 1001), ((2, 12, 102), 1002), ((4, 14, 104), 1004)])\n ),\n Suite.test(\n \"put3D overlapping k2 and k3\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(1), Nat.equal, natKey(10), Nat.equal, natKey(100), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1000), ((2, 12, 102), 1002), ((4, 14, 104), 1004), ((1, 10, 100), 1001)])\n ),\n Suite.test(\n \"put3D overlapping all\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(trie3D, natKey(0), Nat.equal, natKey(10), Nat.equal, natKey(100), Nat.equal, 1001)),\n arrayTest3D([((0, 10, 100), 1001), ((2, 12, 102), 1002), ((4, 14, 104), 1004)])\n ),\n Suite.test(\n \"put3D empty\",\n prettyArray3D(Trie.put3D<Nat, Nat, Nat, Nat>(Trie.empty(), natKey(1), Nat.equal, natKey(11), Nat.equal, natKey(101), Nat.equal, 1001)),\n arrayTest3D([((1, 11, 101), 1001)])\n ),\n Suite.test(\n \"remove success, new trie\",\n prettyArray(Trie.remove<Nat, Nat>(trie1, natKey(2), Nat.equal).0),\n arrayTest([(0, 10), (4, 14)])\n ),\n Suite.test(\n \"remove success, old value\",\n Trie.remove<Nat, Nat>(trie1, natKey(2), Nat.equal).1,\n M.equals(T.optional(T.natTestable, ?12))\n ),\n Suite.test(\n \"remove failure, new trie\",\n prettyArray(Trie.remove<Nat, Nat>(trie1, natKey(1), Nat.equal).0),\n arrayTest([(0, 10), (2, 12), (4, 14)])\n ),\n Suite.test(\n \"remove failure, old value\",\n Trie.remove<Nat, Nat>(trie1, natKey(1), Nat.equal).1,\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"remove empty, new trie\",\n prettyArray(Trie.remove<Nat, Nat>(Trie.empty(), natKey(1), Nat.equal).0),\n arrayTest([])\n ),\n Suite.test(\n \"remove empty, old value\",\n Trie.remove<Nat, Nat>(Trie.empty(), natKey(1), Nat.equal).1,\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"removeThen success old value\",\n Trie.removeThen<Nat, Nat, Nat>(\n trie1,\n natKey(0),\n Nat.equal,\n func(newTrie, oldV) = oldV,\n func _ = Debug.trap \"unreachable\"\n ),\n M.equals(T.nat(10))\n ),\n Suite.test(\n \"removeThen success new trie\",\n prettyArray(\n Trie.removeThen<Nat, Nat, Trie.Trie<Nat, Nat>>(\n trie1,\n natKey(0),\n Nat.equal,\n func(newTrie, oldV) = newTrie,\n func _ = Debug.trap \"unreachable\"\n )\n ),\n arrayTest([(2, 12), (4, 14)])\n ),\n Suite.test(\n \"removeThen failure\",\n Trie.removeThen<Nat, Nat, Nat>(\n trie1,\n natKey(1),\n Nat.equal,\n func _ = Debug.trap \"unreachable\",\n func() = 99\n ),\n M.equals(T.nat(99))\n ),\n Suite.test(\n \"removeThen empty\",\n Trie.removeThen<Nat, Nat, Nat>(\n Trie.empty() : Trie.Trie<Nat, Nat>,\n natKey(1),\n Nat.equal,\n func _ = Debug.trap \"unreachable\",\n func() = 99\n ),\n M.equals(T.nat(99))\n ),\n Suite.test(\n \"remove2D success, new trie\",\n prettyArray2D(Trie.remove2D<Nat, Nat, Nat>(trie2D1, natKey(2), Nat.equal, natKey(12), Nat.equal).0),\n arrayTest2D([((0, 10), 100), ((4, 14), 104)])\n ),\n Suite.test(\n \"remove2D success, old value\",\n Trie.remove2D<Nat, Nat, Nat>(trie2D1, natKey(2), Nat.equal, natKey(12), Nat.equal).1,\n M.equals(T.optional(T.natTestable, ?102))\n ),\n Suite.test(\n \"remove2D failure, new trie\",\n prettyArray2D(Trie.remove2D<Nat, Nat, Nat>(trie2D1, natKey(1), Nat.equal, natKey(11), Nat.equal).0),\n arrayTest2D([((0, 10), 100), ((2, 12), 102), ((4, 14), 104)])\n ),\n Suite.test(\n \"remove2D failure, old value\",\n Trie.remove2D<Nat, Nat, Nat>(trie2D1, natKey(1), Nat.equal, natKey(11), Nat.equal).1,\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"remove2D failure empty, new trie\",\n prettyArray2D(Trie.remove2D<Nat, Nat, Nat>(Trie.empty(), natKey(1), Nat.equal, natKey(11), Nat.equal).0),\n arrayTest2D([])\n ),\n Suite.test(\n \"remove2D failure empty, old value\",\n Trie.remove2D<Nat, Nat, Nat>(Trie.empty(), natKey(1), Nat.equal, natKey(11), Nat.equal).1,\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"remove3D success, new trie\",\n prettyArray3D(Trie.remove3D<Nat, Nat, Nat, Nat>(trie3D, natKey(2), Nat.equal, natKey(12), Nat.equal, natKey(102), Nat.equal).0),\n arrayTest3D([((0, 10, 100), 1000), ((4, 14, 104), 1004)])\n ),\n Suite.test(\n \"remove3D success, old value\",\n Trie.remove3D<Nat, Nat, Nat, Nat>(trie3D, natKey(2), Nat.equal, natKey(12), Nat.equal, natKey(102), Nat.equal).1,\n M.equals(T.optional(T.natTestable, ?1002 : ?Nat))\n ),\n Suite.test(\n \"remove3D failure, new trie\",\n prettyArray3D(Trie.remove3D<Nat, Nat, Nat, Nat>(trie3D, natKey(1), Nat.equal, natKey(11), Nat.equal, natKey(101), Nat.equal).0),\n arrayTest3D([((0, 10, 100), 1000), ((2, 12, 102), 1002), ((4, 14, 104), 1004)])\n ),\n Suite.test(\n \"remove3D failure, old value\",\n Trie.remove3D<Nat, Nat, Nat, Nat>(trie3D, natKey(1), Nat.equal, natKey(11), Nat.equal, natKey(101), Nat.equal).1,\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"remove3D failure empty, new trie\",\n prettyArray3D(Trie.remove3D<Nat, Nat, Nat, Nat>(Trie.empty(), natKey(1), Nat.equal, natKey(11), Nat.equal, natKey(101), Nat.equal).0),\n arrayTest3D([])\n ),\n Suite.test(\n \"remove3D failure empty, old value\",\n Trie.remove3D<Nat, Nat, Nat, Nat>(Trie.empty(), natKey(1), Nat.equal, natKey(11), Nat.equal, natKey(101), Nat.equal).1,\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n Suite.test(\n \"mergeDisjoint2D\",\n prettyArray(Trie.mergeDisjoint2D<Nat, Nat, Nat>(trie2D2, Nat.equal, Nat.equal)),\n arrayTest([(11, 101), (21, 201), (12, 102), (13, 103), (23, 203), (33, 303)])\n ),\n Suite.test(\n \"mergeDisjoint2D empty\",\n prettyArray(Trie.mergeDisjoint2D<Nat, Nat, Nat>(Trie.empty(), Nat.equal, Nat.equal)),\n arrayTest([])\n )\n ]\n);\n\n// FIXME add tests for bitpos functions\n// FIXME test structure of resulting trie, instead of flattening to array\n\nSuite.run(suite);\n\n// Assertion tests\ndebug {\n type Trie<K, V> = Trie.Trie<K, V>;\n type Key<K> = Trie.Key<K>;\n\n func key(i : Nat) : Key<Text> {\n let t = Nat.toText i;\n { key = t; hash = Text.hash t }\n };\n\n let max = 100;\n\n // put k-v elements, one by one (but hashes are expected random).\n Debug.print \"Trie.put\";\n var t : Trie<Text, Nat> = Trie.empty();\n for (i in Iter.range(0, max - 1)) {\n let (t1_, x) = Trie.put<Text, Nat>(t, key i, Text.equal, i);\n assert (Option.isNull(x));\n assert Trie.isValid(t1_, false);\n t := t1_\n };\n assert Trie.size(t) == max;\n\n // remove all elements, one by one (but hashes are expected random).\n do {\n Debug.print \"Trie.remove\";\n var t1 = t;\n for (i in Iter.range(0, max - 1)) {\n let (t1_, x) = Trie.remove<Text, Nat>(t1, key i, Text.equal);\n assert Trie.isValid(t1_, false);\n assert (Option.isSome(x));\n t1 := t1_\n }\n };\n\n // filter all elements away, one by one (but hashes are expected random).\n do {\n Debug.print \"Trie.filter\";\n var t1 = t;\n for (i in Iter.range(0, max - 1)) {\n t1 := Trie.filter(t1, func(t : Text, n : Nat) : Bool { n != i });\n assert Trie.isValid(t1, false);\n assert Trie.size(t1) == (max - (i + 1) : Nat)\n }\n };\n\n // filter-map all elements away, one by one (but hashes are expected random).\n do {\n Debug.print \"Trie.mapFilter\";\n var t1 = t;\n for (i in Iter.range(0, max - 1)) {\n t1 := Trie.mapFilter(\n t1,\n func(t : Text, n : Nat) : ?Nat {\n if (n != i) ?n else null\n }\n );\n assert Trie.isValid(t1, false);\n assert Trie.size(t1) == (max - (i + 1) : Nat)\n }\n }\n}\n"},"int8Test.mo":{"content":"import Debug \"mo:base/Debug\";\nimport Int8 \"mo:base/Int8\";\n\nassert (Int8.fromIntWrap(256) == (0 : Int8));\nassert (Int8.fromIntWrap(-256) == (0 : Int8));\nassert (Int8.fromIntWrap(128) == (-128 : Int8));\nassert (Int8.fromIntWrap(255) == (-1 : Int8))\n"},"orderTest.mo":{"content":"import Order \"mo:base/Order\";\nimport Debug \"mo:base/Debug\";\n\nDebug.print(\"Order\");\n\ndo {\n Debug.print(\" isLess\");\n\n assert (Order.isLess(#less));\n assert (not Order.isLess(#equal));\n assert (not Order.isLess(#greater))\n};\n\ndo {\n Debug.print(\" isEqual\");\n\n assert (not Order.isEqual(#less));\n assert (Order.isEqual(#equal));\n assert (not Order.isEqual(#greater))\n};\n\ndo {\n Debug.print(\" isGreater\");\n\n assert (not Order.isGreater(#less));\n assert (not Order.isGreater(#equal));\n assert (Order.isGreater(#greater))\n}\n"},"textTest.mo":{"content":"import Debug \"mo:base/Debug\";\nimport Text \"mo:base/Text\";\nimport Blob \"mo:base/Blob\";\nimport Iter \"mo:base/Iter\";\nimport Char \"mo:base/Char\";\nimport Order \"mo:base/Order\";\nimport Array \"mo:base/Array\";\nimport Nat32 \"mo:base/Nat32\";\n\nimport Suite \"mo:matchers/Suite\";\nimport M \"mo:matchers/Matchers\";\nimport T \"mo:matchers/Testable\";\n\nlet { run; test; suite } = Suite;\n\nfunc charT(c : Char) : T.TestableItem<Char> = {\n item = c;\n display = Text.fromChar;\n equals = Char.equal\n};\n\nfunc blobT(b : Blob) : T.TestableItem<Blob> = {\n item = b;\n display = func(b : Blob) : Text { debug_show (b) };\n equals = Blob.equal\n};\n\nfunc ordT(o : Order.Order) : T.TestableItem<Order.Order> = {\n item = o;\n display = func(o : Order.Order) : Text { debug_show (o) };\n equals = Order.equal\n};\n\nfunc optTextT(ot : ?Text) : T.TestableItem<?Text> = T.optional(T.textTestable, ot);\n\n// TODO: generalize and move to Iter.mo\nfunc iterT(c : [Char]) : T.TestableItem<Iter.Iter<Char>> = {\n item = c.vals();\n display = Text.fromIter; // not this will only print the remainder of cs1 below\n equals = func(cs1 : Iter.Iter<Char>, cs2 : Iter.Iter<Char>) : Bool {\n loop {\n switch (cs1.next(), cs2.next()) {\n case (null, null) return true;\n case (?c1, ?c2) if (c1 != c2) return false;\n case (_, _) return false\n }\n }\n }\n};\n\n// TODO: generalize and move to Iter.mo\nfunc textIterT(c : [Text]) : T.TestableItem<Iter.Iter<Text>> = {\n item = c.vals();\n display = func(ts : Iter.Iter<Text>) : Text { Text.join(\",\", ts) };\n // not this will only print the remainder of cs1 below\n equals = func(ts1 : Iter.Iter<Text>, ts2 : Iter.Iter<Text>) : Bool {\n loop {\n switch (ts1.next(), ts2.next()) {\n case (null, null) return true;\n case (?t1, ?t2) if (t1 != t2) return false;\n case (_, _) return false\n }\n }\n }\n};\n\nrun(\n suite(\n \"size\",\n [\n test(\n \"size-0\",\n Text.size(\"\"),\n M.equals(T.nat 0)\n ),\n test(\n \"size-1\",\n Text.size(\"a\"),\n M.equals(T.nat 1)\n ),\n test(\n \"size-2\",\n Text.size(\"abcdefghijklmnopqrstuvwxyz\"),\n M.equals(T.nat 26)\n ),\n test(\n \"size-3\",\n Text.size(\"☃\"),\n M.equals(T.nat 1)\n ),\n test(\n \"size-4\",\n Text.size(\"☃☃\"),\n M.equals(T.nat 2)\n )\n ]\n )\n);\n\nrun(\n suite(\n \"toIter\",\n [\n test(\n \"toIter-0\",\n Text.toIter(\"\"),\n M.equals(iterT([]))\n ),\n test(\n \"toIter-1\",\n Text.toIter(\"a\"),\n M.equals(iterT(['a']))\n ),\n test(\n \"toIter-2\",\n Text.toIter(\"abc\"),\n M.equals(iterT(['a', 'b', 'c']))\n ),\n do {\n let a = Array.tabulate<Char>(1000, func i = Char.fromNat32(65 +% Nat32.fromIntWrap(i % 26)));\n test(\n \"fromIter-2\",\n Text.toIter(Text.join(\"\", Array.map(a, Char.toText).vals())),\n M.equals(iterT a)\n )\n }\n ]\n )\n);\n\nrun(\n suite(\n \"fromIter\",\n [\n test(\n \"fromIter-0\",\n Text.fromIter(([].vals())),\n M.equals(T.text(\"\"))\n ),\n test(\n \"fromIter-1\",\n Text.fromIter((['a'].vals())),\n M.equals(T.text \"a\")\n ),\n test(\n \"fromIter-2\",\n Text.fromIter((['a', 'b', 'c'].vals())),\n M.equals(T.text \"abc\")\n ),\n do {\n let a = Array.tabulate<Char>(1000, func i = Char.fromNat32(65 +% Nat32.fromIntWrap(i % 26)));\n test(\n \"fromIter-3\",\n Text.fromIter(a.vals()),\n M.equals(T.text(Text.join(\"\", Array.map(a, Char.toText).vals())))\n )\n }\n ]\n )\n);\n\nrun(\n suite(\n \"concat\",\n [\n test(\n \"concat-0\",\n Text.concat(\"\", \"\"),\n M.equals(T.text(\"\"))\n ),\n test(\n \"concat-1\",\n Text.concat(\"\", \"b\"),\n M.equals(T.text \"b\")\n ),\n test(\n \"concat-2\",\n Text.concat(\"a\", \"b\"),\n M.equals(T.text \"ab\")\n ),\n test(\n \"concat-3\",\n Text.concat(\"abcdefghijklmno\", \"pqrstuvwxyz\"),\n M.equals(T.text \"abcdefghijklmnopqrstuvwxyz\")\n )\n ]\n )\n);\n\nrun(\n suite(\n \"join\",\n [\n test(\n \"join-0\",\n Text.join(\"\", ([\"\", \"\"].vals())),\n M.equals(T.text(\"\"))\n ),\n test(\n \"join-1\",\n Text.join(\"\", ([\"\", \"b\"].vals())),\n M.equals(T.text \"b\")\n ),\n test(\n \"join-2\",\n Text.join(\"\", ([\"a\", \"bb\", \"ccc\", \"dddd\"].vals())),\n M.equals(T.text \"abbcccdddd\")\n ),\n do {\n let a = Array.tabulate<Char>(1000, func i = Char.fromNat32(65 +% Nat32.fromIntWrap(i % 26)));\n test(\n \"join-3\",\n Text.join(\"\", Array.map(a, Char.toText).vals()),\n M.equals(T.text(Text.fromIter(a.vals())))\n )\n },\n test(\n \"join-4\",\n Text.join(\"\", ([].vals())),\n M.equals(T.text \"\")\n ),\n test(\n \"join-5\",\n Text.join(\"\", ([\"aaa\"].vals())),\n M.equals(T.text \"aaa\")\n )\n ]\n )\n);\n\nrun(\n suite(\n \"join\",\n [\n test(\n \"join-0\",\n Text.join(\",\", ([\"\", \"\"].vals())),\n M.equals(T.text(\",\"))\n ),\n test(\n \"join-1\",\n Text.join(\",\", ([\"\", \"b\"].vals())),\n M.equals(T.text \",b\")\n ),\n test(\n \"join-2\",\n Text.join(\",\", ([\"a\", \"bb\", \"ccc\", \"dddd\"].vals())),\n M.equals(T.text \"a,bb,ccc,dddd\")\n ),\n do {\n let a = Array.tabulate<Char>(1000, func i = Char.fromNat32(65 +% Nat32.fromIntWrap(i % 26)));\n test(\n \"join-3\",\n Text.join(\"\", Array.map(a, Char.toText).vals()),\n M.equals(T.text(Text.fromIter(a.vals())))\n )\n },\n test(\n \"join-4\",\n Text.join(\",\", ([].vals())),\n M.equals(T.text \"\")\n ),\n test(\n \"join-5\",\n Text.join(\",\", ([\"aaa\"].vals())),\n M.equals(T.text \"aaa\")\n )\n ]\n )\n);\n\nrun(\n suite(\n \"split\",\n [\n test(\n \"split-char-empty\",\n Text.split(\"\", #char ';'),\n M.equals(textIterT([]))\n ),\n test(\n \"split-char-none\",\n Text.split(\"abc\", #char ';'),\n M.equals(textIterT([\"abc\"]))\n ),\n test(\n \"split-char-empties2\",\n Text.split(\";\", #char ';'),\n M.equals(textIterT([\"\", \"\"]))\n ),\n test(\n \"split-char-empties3\",\n Text.split(\";;\", #char ';'),\n M.equals(textIterT([\"\", \"\", \"\"]))\n ),\n test(\n \"split-char-singles\",\n Text.split(\"a;b;;c;;;d\", #char ';'),\n M.equals(textIterT([\"a\", \"b\", \"\", \"c\", \"\", \"\", \"d\"]))\n ),\n test(\n \"split-char-mixed\",\n Text.split(\"a;;;ab;;abc;\", #char ';'),\n M.equals(textIterT([\"a\", \"\", \"\", \"ab\", \"\", \"abc\", \"\"]))\n ),\n do {\n let a = Array.tabulate<Text>(1000, func _ = \"abc\");\n let t = Text.join(\";\", a.vals());\n test(\n \"split-char-large\",\n Text.split(t, #char ';'),\n M.equals(textIterT a)\n )\n },\n do {\n let a = Array.tabulate<Text>(100000, func _ = \"abc\");\n let t = Text.join(\";\", a.vals());\n test(\n \"split-char-very-large\",\n Text.split(t, #char ';'),\n M.equals(textIterT a)\n )\n }\n ]\n )\n);\n\ndo {\n let pat : Text.Pattern = #predicate(func(c : Char) : Bool { c == ';' or c == '!' });\n run(\n suite(\n \"split\",\n [\n test(\n \"split-pred-empty\",\n Text.split(\"\", pat),\n M.equals(textIterT([]))\n ),\n test(\n \"split-pred-none\",\n Text.split(\"abc\", pat),\n M.equals(textIterT([\"abc\"]))\n ),\n test(\n \"split-pred-empties2\",\n Text.split(\";\", pat),\n M.equals(textIterT([\"\", \"\"]))\n ),\n test(\n \"split-pred-empties3\",\n Text.split(\";!\", pat),\n M.equals(textIterT([\"\", \"\", \"\"]))\n ),\n test(\n \"split-pred-singles\",\n Text.split(\"a;b;!c!;;d\", pat),\n M.equals(textIterT([\"a\", \"b\", \"\", \"c\", \"\", \"\", \"d\"]))\n ),\n test(\n \"split-pred-mixed\",\n Text.split(\"a;!;ab;!abc;\", pat),\n M.equals(textIterT([\"a\", \"\", \"\", \"ab\", \"\", \"abc\", \"\"]))\n ),\n do {\n let a = Array.tabulate<Text>(1000, func _ = \"abc\");\n let t = Text.join(\";\", a.vals());\n test(\n \"split-pred-large\",\n Text.split(t, pat),\n M.equals(textIterT a)\n )\n },\n do {\n let a = Array.tabulate<Text>(10000, func _ = \"abc\");\n let t = Text.join(\";\", a.vals());\n test(\n \"split-pred-very-large\",\n Text.split(t, pat),\n M.equals(textIterT a)\n )\n }\n ]\n )\n )\n};\n\ndo {\n let pat : Text.Pattern = #text \"PAT\";\n run(\n suite(\n \"split\",\n [\n test(\n \"split-pat-empty\",\n Text.split(\"\", pat),\n M.equals(textIterT([]))\n ),\n test(\n \"split-pat-none\",\n Text.split(\"abc\", pat),\n M.equals(textIterT([\"abc\"]))\n ),\n test(\n \"split-pat-empties2\",\n Text.split(\"PAT\", pat),\n M.equals(textIterT([\"\", \"\"]))\n ),\n test(\n \"split-pat-empties3\",\n Text.split(\"PATPAT\", pat),\n M.equals(textIterT([\"\", \"\", \"\"]))\n ),\n test(\n \"split-pat-singles\",\n Text.split(\"aPATbPATPATcPATPATPATd\", pat),\n M.equals(textIterT([\"a\", \"b\", \"\", \"c\", \"\", \"\", \"d\"]))\n ),\n test(\n \"split-pat-mixed\",\n Text.split(\"aPATPATPATabPATPATabcPAT\", pat),\n M.equals(textIterT([\"a\", \"\", \"\", \"ab\", \"\", \"abc\", \"\"]))\n ),\n do {\n let a = Array.tabulate<Text>(1000, func _ = \"abc\");\n let t = Text.join(\"PAT\", a.vals());\n test(\n \"split-pat-large\",\n Text.split(t, pat),\n M.equals(textIterT a)\n )\n },\n do {\n let a = Array.tabulate<Text>(10000, func _ = \"abc\");\n let t = Text.join(\"PAT\", a.vals());\n test(\n \"split-pat-very-large\",\n Text.split(t, pat),\n M.equals(textIterT a)\n )\n }\n ]\n )\n )\n};\n\nrun(\n suite(\n \"tokens\",\n [\n test(\n \"tokens-char-empty\",\n Text.tokens(\"\", #char ';'),\n M.equals(textIterT([]))\n ),\n test(\n \"tokens-char-none\",\n Text.tokens(\"abc\", #char ';'),\n M.equals(textIterT([\"abc\"]))\n ),\n test(\n \"tokens-char-empties2\",\n Text.tokens(\";\", #char ';'),\n M.equals(textIterT([]))\n ),\n test(\n \"tokens-char-empties3\",\n Text.tokens(\";;\", #char ';'),\n M.equals(textIterT([]))\n ),\n test(\n \"tokens-char-singles\",\n Text.tokens(\"a;b;;c;;;d\", #char ';'),\n M.equals(textIterT([\"a\", \"b\", \"c\", \"d\"]))\n ),\n test(\n \"tokens-char-mixed\",\n Text.tokens(\"a;;;ab;;abc;\", #char ';'),\n M.equals(textIterT([\"a\", \"ab\", \"abc\"]))\n ),\n do {\n let a = Array.tabulate<Text>(1000, func _ = \"abc\");\n let t = Text.join(\";;\", a.vals());\n test(\n \"tokens-char-large\",\n Text.tokens(t, #char ';'),\n M.equals(textIterT a)\n )\n },\n do {\n let a = Array.tabulate<Text>(100000, func _ = \"abc\");\n let t = Text.join(\";;\", a.vals());\n test(\n \"tokens-char-very-large\",\n Text.tokens(t, #char ';'),\n M.equals(textIterT a)\n )\n }\n ]\n )\n);\n\nrun(\n suite(\n \"startsWith\",\n [\n test(\n \"startsWith-both-empty\",\n Text.startsWith(\"\", #text \"\"),\n M.equals(T.bool true)\n ),\n test(\n \"startsWith-empty-text\",\n Text.startsWith(\"\", #text \"abc\"),\n M.equals(T.bool false)\n ),\n test(\n \"startsWith-empty-pat\",\n Text.startsWith(\"abc\", #text \"\"),\n M.equals(T.bool true)\n ),\n test(\n \"startsWith-1\",\n Text.startsWith(\"a\", #text \"b\"),\n M.equals(T.bool false)\n ),\n test(\n \"startsWith-2\",\n Text.startsWith(\"abc\", #text \"abc\"),\n M.equals(T.bool true)\n ),\n test(\n \"startsWith-3\",\n Text.startsWith(\"abcd\", #text \"ab\"),\n M.equals(T.bool true)\n ),\n test(\n \"startsWith-4\",\n Text.startsWith(\"abcdefghijklmnopqrstuvwxyz\", #text \"abcdefghijklmno\"),\n M.equals(T.bool true)\n )\n ]\n )\n);\n\nrun(\n suite(\n \"endsWith\",\n [\n test(\n \"endsWith-both-empty\",\n Text.endsWith(\"\", #text \"\"),\n M.equals(T.bool true)\n ),\n test(\n \"endsWith-empty-text\",\n Text.endsWith(\"\", #text \"abc\"),\n M.equals(T.bool false)\n ),\n test(\n \"endsWith-empty-pat\",\n Text.endsWith(\"abc\", #text \"\"),\n M.equals(T.bool true)\n ),\n test(\n \"endsWith-1\",\n Text.endsWith(\"a\", #text \"b\"),\n M.equals(T.bool false)\n ),\n test(\n \"endsWith-2\",\n Text.endsWith(\"abc\", #text \"abc\"),\n M.equals(T.bool true)\n ),\n test(\n \"endsWith-3\",\n Text.endsWith(\"abcd\", #text \"cd\"),\n M.equals(T.bool true)\n ),\n test(\n \"endsWith-4\",\n Text.endsWith(\"abcdefghijklmnopqrstuvwxyz\", #text \"pqrstuvwxyz\"),\n M.equals(T.bool true)\n )\n ]\n )\n);\n\nrun(\n suite(\n \"contains\",\n [\n test(\n \"contains-start\",\n Text.contains(\"abcd\", #text \"ab\"),\n M.equals(T.bool true)\n ),\n test(\n \"contains-empty\",\n Text.contains(\"abc\", #text \"\"),\n M.equals(T.bool true)\n ),\n test(\n \"contains-false\",\n Text.contains(\"ab\", #text \"bc\"),\n M.equals(T.bool false)\n ),\n test(\n \"contains-exact\",\n Text.contains(\"abc\", #text \"abc\"),\n M.equals(T.bool true)\n ),\n test(\n \"contains-within\",\n Text.contains(\"abcdefghijklmnopqrstuvwxyz\", #text \"qrst\"),\n M.equals(T.bool true)\n ),\n test(\n \"contains-front\",\n Text.contains(\"abcdefghijklmnopqrstuvwxyz\", #text \"abcdefg\"),\n M.equals(T.bool true)\n ),\n test(\n \"contains-end\",\n Text.contains(\"abcdefghijklmnopqrstuvwxyz\", #text \"xyz\"),\n M.equals(T.bool true)\n ),\n test(\n \"contains-false\",\n Text.contains(\"abcdefghijklmnopqrstuvwxyz\", #text \"lkj\"),\n M.equals(T.bool false)\n ),\n test(\n \"contains-empty-nonempty\",\n Text.contains(\"\", #text \"xyz\"),\n M.equals(T.bool false)\n )\n ]\n )\n);\n\nrun(\n suite(\n \"replace\",\n [\n test(\n \"replace-start\",\n Text.replace(\"abcd\", #text \"ab\", \"AB\"),\n M.equals(T.text \"ABcd\")\n ),\n test(\n \"replace-empty\",\n Text.replace(\"abc\", #text \"\", \"AB\"),\n M.equals(T.text \"ABaABbABcAB\")\n ),\n test(\n \"replace-none\",\n Text.replace(\"ab\", #text \"bc\", \"AB\"),\n M.equals(T.text \"ab\")\n ),\n test(\n \"replace-exact\",\n Text.replace(\"ab\", #text \"ab\", \"AB\"),\n M.equals(T.text \"AB\")\n ),\n test(\n \"replace-several\",\n Text.replace(\"abcdabghijabmnopqrstuabwxab\", #text \"ab\", \"AB\"),\n M.equals(T.text \"ABcdABghijABmnopqrstuABwxAB\")\n ),\n test(\n \"replace-delete\",\n Text.replace(\"abcdabghijabmnopqrstuabwxab\", #text \"ab\", \"\"),\n M.equals(T.text \"cdghijmnopqrstuwx\")\n ),\n test(\n \"replace-pred\",\n Text.replace(\"abcdefghijklmnopqrstuvwxyz\", #predicate(func(c : Char) : Bool { c < 'm' }), \"\"),\n M.equals(T.text \"mnopqrstuvwxyz\")\n ),\n test(\n \"replace-partial\",\n Text.replace(\"123\", #text \"124\", \"ABC\"),\n M.equals(T.text \"123\")\n ),\n test(\n \"replace-partial-2\",\n Text.replace(\"12341235124\", #text \"124\", \"ABC\"),\n M.equals(T.text \"12341235ABC\")\n ),\n test(\n \"replace-partial-3\",\n Text.replace(\"111234123511124\", #text \"124\", \"ABC\"),\n M.equals(T.text \"111234123511ABC\")\n )\n ]\n )\n);\n\nrun(\n suite(\n \"stripStart\",\n [\n test(\n \"stripStart-none\",\n Text.stripStart(\"cd\", #text \"ab\"),\n M.equals(optTextT(null))\n ),\n test(\n \"stripStart-one\",\n Text.stripStart(\"abcd\", #text \"ab\"),\n M.equals(optTextT(?\"cd\"))\n ),\n test(\n \"stripStart-two\",\n Text.stripStart(\"abababcd\", #text \"ab\"),\n M.equals(optTextT(?\"ababcd\"))\n ),\n test(\n \"stripStart-only\",\n Text.stripStart(\"ababababab\", #text \"ab\"),\n M.equals(optTextT(?\"abababab\"))\n ),\n test(\n \"stripStart-empty\",\n Text.stripStart(\"abcdef\", #text \"\"),\n M.equals(optTextT(?\"abcdef\"))\n ),\n test(\n \"stripStart-tooshort\",\n Text.stripStart(\"abcdef\", #text \"abcdefg\"),\n M.equals(optTextT(null))\n )\n ]\n )\n);\n\nrun(\n suite(\n \"stripEnd\",\n [\n test(\n \"stripEnd-exact\",\n Text.stripEnd(\"cd\", #text \"cd\"),\n M.equals(optTextT(?\"\"))\n ),\n test(\n \"stripEnd-one\",\n Text.stripEnd(\"abcd\", #text \"cd\"),\n M.equals(optTextT(?\"ab\"))\n ),\n test(\n \"stripEnd-three\",\n Text.stripEnd(\"abcdcdcd\", #text \"cd\"),\n M.equals(optTextT(?\"abcdcd\"))\n ),\n test(\n \"stripEnd-many\",\n Text.stripEnd(\"cdcdcdcdcdcdcd\", #text \"cd\"),\n M.equals(optTextT(?\"cdcdcdcdcdcd\"))\n ),\n test(\n \"stripEnd-empty-pat\",\n Text.stripEnd(\"abcdef\", #text \"\"),\n M.equals(optTextT(?\"abcdef\"))\n ),\n test(\n \"stripEnd-empty\",\n Text.stripEnd(\"\", #text \"cd\"),\n M.equals(optTextT null)\n ),\n test(\n \"stripEnd-tooshort\",\n Text.stripEnd(\"bcdef\", #text \"abcdef\"),\n M.equals(optTextT null)\n )\n ]\n )\n);\n\nrun(\n suite(\n \"trimStart\",\n [\n test(\n \"trimStart-none\",\n Text.trimStart(\"cd\", #text \"ab\"),\n M.equals(T.text \"cd\")\n ),\n test(\n \"trimStart-one\",\n Text.trimStart(\"abcd\", #text \"ab\"),\n M.equals(T.text \"cd\")\n ),\n test(\n \"trimStart-two\",\n Text.trimStart(\"abababcd\", #text \"ab\"),\n M.equals(T.text \"cd\")\n ),\n test(\n \"trimStart-only\",\n Text.trimStart(\"ababababab\", #text \"ab\"),\n M.equals(T.text \"\")\n ),\n test(\n \"trimStart-empty\",\n Text.trimStart(\"abcdef\", #text \"\"),\n M.equals(T.text \"abcdef\")\n )\n ]\n )\n);\n\nrun(\n suite(\n \"trimEnd\",\n [\n test(\n \"trimEnd-exact\",\n Text.trimEnd(\"cd\", #text \"cd\"),\n M.equals(T.text \"\")\n ),\n test(\n \"trimEnd-one\",\n Text.trimEnd(\"abcd\", #text \"cd\"),\n M.equals(T.text \"ab\")\n ),\n test(\n \"trimEnd-three\",\n Text.trimEnd(\"abcdcdcd\", #text \"cd\"),\n M.equals(T.text \"ab\")\n ),\n test(\n \"trimEnd-many\",\n Text.trimEnd(\"cdcdcdcdcdcdcd\", #text \"cd\"),\n M.equals(T.text \"\")\n ),\n test(\n \"trimEnd-empty-pat\",\n Text.trimEnd(\"abcdef\", #text \"\"),\n M.equals(T.text \"abcdef\")\n ),\n test(\n \"trimEnd-empty\",\n Text.trimEnd(\"\", #text \"cd\"),\n M.equals(T.text \"\")\n )\n ]\n )\n);\n\nrun(\n suite(\n \"trim\",\n [\n test(\n \"trim-exact\",\n Text.trim(\"cd\", #text \"cd\"),\n M.equals(T.text \"\")\n ),\n test(\n \"trim-one\",\n Text.trim(\"cdabcd\", #text \"cd\"),\n M.equals(T.text \"ab\")\n ),\n test(\n \"trim-three\",\n Text.trim(\"cdcdcdabcdcdcd\", #text \"cd\"),\n M.equals(T.text \"ab\")\n ),\n test(\n \"trim-many\",\n Text.trim(\"cdcdcdcdcdcdcd\", #text \"cd\"),\n M.equals(T.text \"\")\n ),\n test(\n \"trim-empty-pat\",\n Text.trim(\"abcdef\", #text \"\"),\n M.equals(T.text \"abcdef\")\n ),\n test(\n \"trim-empty\",\n Text.trim(\"\", #text \"cd\"),\n M.equals(T.text \"\")\n )\n ]\n )\n);\n\nrun(\n suite(\n \"compare\",\n [\n test(\n \"compare-empties\",\n Text.compare(\"\", \"\"),\n M.equals(ordT(#equal))\n ),\n test(\n \"compare-empty-nonempty\",\n Text.compare(\"\", \"a\"),\n M.equals(ordT(#less))\n ),\n test(\n \"compare-nonempty-empty\",\n Text.compare(\"a\", \"\"),\n M.equals(ordT(#greater))\n ),\n test(\n \"compare-a-a\",\n Text.compare(\"a\", \"a\"),\n M.equals(ordT(#equal))\n ),\n test(\n \"compare-a-b\",\n Text.compare(\"a\", \"b\"),\n M.equals(ordT(#less))\n ),\n test(\n \"compare-b-a\",\n Text.compare(\"b\", \"a\"),\n M.equals(ordT(#greater))\n )\n ]\n )\n);\n\ndo {\n let cmp = Char.compare;\n run(\n suite(\n \"compareWith\",\n [\n test(\n \"compareWith-empties\",\n Text.compareWith(\"\", \"\", cmp),\n M.equals(ordT(#equal))\n ),\n test(\n \"compareWith-empty\",\n Text.compareWith(\"abc\", \"\", cmp),\n M.equals(ordT(#greater))\n ),\n test(\n \"compareWith-equal-nonempty\",\n Text.compareWith(\"abc\", \"abc\", cmp),\n M.equals(ordT(#equal))\n ),\n test(\n \"compareWith-less-nonempty\",\n Text.compareWith(\"abc\", \"abd\", cmp),\n M.equals(ordT(#less))\n ),\n test(\n \"compareWith-less-nonprefix\",\n Text.compareWith(\"abc\", \"abcd\", cmp),\n M.equals(ordT(#less))\n ),\n test(\n \"compareWith-empty-nonempty\",\n Text.compareWith(\"\", \"abcd\", cmp),\n M.equals(ordT(#less))\n ),\n test(\n \"compareWith-prefix\",\n Text.compareWith(\"abcd\", \"abc\", cmp),\n M.equals(ordT(#greater))\n )\n ]\n )\n )\n};\n\ndo {\n let cmp = func(c1 : Char, c2 : Char) : Order.Order {\n switch (Char.compare(c1, c2)) {\n case (#less) #greater;\n case (#equal) #equal;\n case (#greater) #less\n }\n };\n run(\n suite(\n \"compareWith-flip\",\n [\n test(\n \"compareWith-flip-greater\",\n Text.compareWith(\"abc\", \"abd\", cmp),\n M.equals(ordT(#greater))\n ),\n test(\n \"compareWith-flip-less\",\n Text.compareWith(\"abd\", \"abc\", cmp),\n M.equals(ordT(#less))\n )\n ]\n )\n )\n};\n\nrun(\n suite(\n \"utf8\",\n [\n test(\n \"encode-literal\",\n Text.encodeUtf8(\"FooBär☃\"),\n M.equals(blobT(\"FooBär☃\"))\n ),\n test(\n \"encode-concat\",\n Text.encodeUtf8(\"Foo\" # \"Bär\" # \"☃\"),\n M.equals(blobT(\"FooBär☃\"))\n ),\n test(\n \"decode-literal-good\",\n Text.decodeUtf8(\"FooBär☃\"),\n M.equals(optTextT(?\"FooBär☃\"))\n ),\n test(\n \"decode-literal-bad1\",\n Text.decodeUtf8(\"\\FF\"),\n M.equals(optTextT(null))\n ),\n test(\n \"decode-literal-bad2\",\n Text.decodeUtf8(\"\\D8\\00t d\"),\n M.equals(optTextT(null))\n )\n ]\n )\n)\n"},"TrieExampleTest.mo":{"content":"import Trie \"mo:base/Trie\";\nimport Text \"mo:base/Text\";\nimport Iter \"mo:base/Iter\";\n\ndebug {\n type Trie<K, V> = Trie.Trie<K, V>;\n type Key<K> = Trie.Key<K>;\n\n func key(t : Text) : Key<Text> { { key = t; hash = Text.hash t } };\n\n let t0 : Trie<Text, Nat> = Trie.empty();\n let t1 : Trie<Text, Nat> = Trie.put(t0, key \"hello\", Text.equal, 42).0;\n let t2 : Trie<Text, Nat> = Trie.put(t1, key \"world\", Text.equal, 24).0;\n let n : ?Nat = Trie.put(t1, key \"hello\", Text.equal, 0).1;\n assert (n == ?42);\n\n /// True if elements of a form a subset of those of b.\n func isSubSet<X>(a : [X], b : [X], eq : (X, X) -> Bool) : Bool {\n for (x in a.vals()) {\n var found = false;\n label here : () {\n for (y in b.vals()) {\n if (eq(x, y)) { found := true; break here }\n }\n };\n if (not found) { return false }\n };\n return true\n };\n\n // note that `put(\"hello\", ..., 0)` happens \"after\" t2, but map is immutable (applicative).\n let actual : [(Text, Nat)] = Iter.toArray(Trie.iter(t2));\n let expected : [(Text, Nat)] = [(\"hello\", 42), (\"world\", 24)];\n func equalKV(a : (Text, Nat), b : (Text, Nat)) : Bool { a == b };\n assert (isSubSet(actual, expected, equalKV));\n assert (isSubSet(expected, actual, equalKV));\n assert Trie.isValid(t2, false)\n}\n"},"floatTest.mo":{"content":"import Debug \"mo:base/Debug\";\nimport Float \"mo:base/Float\";\n\nDebug.print(\"Float\");\n\ndo {\n Debug.print(\" abs\");\n\n assert (Float.abs(1.1) == 1.1);\n assert (Float.abs(-1.1) == 1.1)\n};\n\ndo {\n Debug.print(\" ceil\");\n\n assert (Float.ceil(1.1) == 2.0)\n};\n\ndo {\n Debug.print(\" floor\");\n\n assert (Float.floor(1.1) == 1.0)\n};\n\ndo {\n Debug.print(\" trunc\");\n\n assert (Float.trunc(1.0012345789) == 1.0)\n};\n\ndo {\n Debug.print(\" nearest\");\n\n assert (Float.nearest(1.00001) == 1.0);\n assert (Float.nearest(1.99999) == 2.0)\n};\n\ndo {\n Debug.print(\" min\");\n\n assert (Float.min(1.1, 2.2) == 1.1)\n};\n\ndo {\n Debug.print(\" max\");\n\n assert (Float.max(1.1, 2.2) == 2.2)\n};\n\ndo {\n Debug.print(\" sin\");\n\n assert (Float.sin(0.0) == 0.0)\n};\n\ndo {\n Debug.print(\" cos\");\n\n assert (Float.cos(0.0) == 1.0)\n};\n\ndo {\n Debug.print(\" toFloat64\");\n\n assert (Float.toInt64(1e10) == (10000000000 : Int64));\n assert (Float.toInt64(-1e10) == (-10000000000 : Int64))\n};\n\ndo {\n Debug.print(\" ofFloat64\");\n\n assert (Float.fromInt64(10000000000) == 1e10);\n assert (Float.fromInt64(-10000000000) == -1e10)\n};\n\ndo {\n Debug.print(\" format\");\n\n assert (Float.format(#exact, 20.12345678901) == \"20.12345678901\");\n assert (Float.format(#fix 6, 20.12345678901) == \"20.123457\");\n assert (Float.format(#exp 9, 20.12345678901) == \"2.012345679e+01\");\n assert (Float.format(#gen 12, 20.12345678901) == \"20.123456789\");\n assert (Float.format(#hex 10, 20.12345678901) == \"0x1.41f9add374p+4\")\n};\n\ndo {\n Debug.print(\" Pi: \" # Float.toText(Float.pi));\n Debug.print(\" arccos(-1.0): \" # Float.toText(Float.arccos(-1.)));\n\n assert (Float.pi == Float.arccos(-1.))\n};\n\ndo {\n Debug.print(\" e: \" # debug_show (Float.toText(Float.e)));\n Debug.print(\" exp(1): \" # debug_show (Float.toText(Float.exp(1))));\n\n assert (Float.e == Float.exp(1))\n}\n"},"bufTest.mo":{"content":"import Prim \"mo:⛔\";\nimport B \"mo:base/Buffer\";\nimport Iter \"mo:base/Iter\";\nimport Option \"mo:base/Option\";\nimport Nat \"mo:base/Nat\";\nimport Hash \"mo:base/Hash\";\nimport Nat32 \"mo:base/Nat32\";\nimport Order \"mo:base/Order\";\n\nimport Suite \"mo:matchers/Suite\";\nimport T \"mo:matchers/Testable\";\nimport M \"mo:matchers/Matchers\";\n\nlet { run; test; suite } = Suite;\n\nlet NatBufferTestable : T.Testable<B.Buffer<Nat>> = object {\n public func display(buffer : B.Buffer<Nat>) : Text {\n B.toText(buffer, Nat.toText)\n };\n public func equals(buffer1 : B.Buffer<Nat>, buffer2 : B.Buffer<Nat>) : Bool {\n B.equal(buffer1, buffer2, Nat.equal)\n }\n};\n\nclass OrderTestable(initItem : Order.Order) : T.TestableItem<Order.Order> {\n public let item = initItem;\n public func display(order : Order.Order) : Text {\n switch (order) {\n case (#less) {\n \"#less\"\n };\n case (#greater) {\n \"#greater\"\n };\n case (#equal) {\n \"#equal\"\n }\n }\n };\n public let equals = Order.equal\n};\n\n/* --------------------------------------- */\nrun(\n suite(\n \"construct\",\n [\n test(\n \"initial size\",\n B.Buffer<Nat>(10).size(),\n M.equals(T.nat(0))\n ),\n test(\n \"initial capacity\",\n B.Buffer<Nat>(10).capacity(),\n M.equals(T.nat(10))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nvar buffer = B.Buffer<Nat>(10);\nfor (i in Iter.range(0, 3)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"add\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(4))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(10))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(2);\nfor (i in Iter.range(0, 3)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"add with capacity change\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(4))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(5))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(0);\nfor (i in Iter.range(0, 3)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"add with capacity change, initial capacity 0\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(4))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(5))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(2);\n\nrun(\n suite(\n \"removeLast on empty buffer\",\n [\n test(\n \"return value\",\n buffer.removeLast(),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(0))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(2))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(2);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"removeLast\",\n [\n test(\n \"return value\",\n buffer.removeLast(),\n M.equals(T.optional<Nat>(T.natTestable, ?5))\n ),\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(5))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nfor (i in Iter.range(0, 5)) {\n ignore buffer.removeLast()\n};\n\nrun(\n suite(\n \"removeLast until empty\",\n [\n test(\n \"return value\",\n buffer.removeLast(),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(0))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(2))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(0);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"remove\",\n [\n test(\n \"return value\",\n buffer.remove(2),\n M.equals(T.nat(2))\n ),\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(5))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 3, 4, 5]))\n ),\n test(\n \"return value\",\n buffer.remove(0),\n M.equals(T.nat(0))\n ),\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(4))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [1, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\nfor (i in Iter.range(0, 2)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"remove last element at capacity\",\n [\n test(\n \"return value\",\n buffer.remove(2),\n M.equals(T.nat(2))\n ),\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(2))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(3))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(0);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nfor (i in Iter.range(0, 5)) {\n ignore buffer.remove(5 - i)\n};\n\nrun(\n suite(\n \"remove until empty\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(0))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(2))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(1);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.filterEntries(func(_, x) = x % 2 == 0);\n\nrun(\n suite(\n \"filterEntries\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(3))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 2, 4]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(1);\nbuffer.filterEntries(func(_, x) = x % 2 == 0);\n\nrun(\n suite(\n \"filterEntries on empty\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(0))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(12);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\nbuffer.filterEntries(func(i, x) = i + x == 2);\n\nrun(\n suite(\n \"filterEntries size down\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(1))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [1]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(5);\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\nbuffer.filterEntries(func(_, _) = false);\n\nrun(\n suite(\n \"filterEntries size down to empty\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(0))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(2))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(10);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"get and getOpt\",\n [\n test(\n \"get\",\n buffer.get(2),\n M.equals(T.nat(2))\n ),\n test(\n \"getOpt success\",\n buffer.getOpt(0),\n M.equals(T.optional(T.natTestable, ?0))\n ),\n test(\n \"getOpt out of bounds\",\n buffer.getOpt(10),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(10);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.put(2, 20);\n\nrun(\n suite(\n \"put\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 20, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(10);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.reserve(6);\n\nrun(\n suite(\n \"decrease capacity\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(6))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(10);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.reserve(20);\n\nrun(\n suite(\n \"increase capacity\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(6))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(20))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(10);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nvar buffer2 = B.Buffer<Nat>(20);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.append(buffer2);\n\nrun(\n suite(\n \"append\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(12))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(18))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(10);\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(0);\n\nbuffer.append(buffer2);\n\nrun(\n suite(\n \"append empty buffer\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(6))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(10))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(10);\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(0, 5)) {\n buffer2.add(i)\n};\n\nbuffer.append(buffer2);\n\nrun(\n suite(\n \"append to empty buffer\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(6))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(10))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(8);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.insert(3, 30);\n\nrun(\n suite(\n \"insert\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(7))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 30, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(8);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.insert(6, 60);\n\nrun(\n suite(\n \"insert at back\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(7))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5, 60]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(8);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.insert(0, 10);\n\nrun(\n suite(\n \"insert at front\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(7))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [10, 0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(6);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer.insert(3, 30);\n\nrun(\n suite(\n \"insert with capacity change\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(7))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(9))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 30, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(5);\n\nbuffer.insert(0, 0);\n\nrun(\n suite(\n \"insert into empty buffer\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(1))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(5))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(0);\n\nbuffer.insert(0, 0);\n\nrun(\n suite(\n \"insert into empty buffer with capacity change\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(1))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(15);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(3, buffer2);\n\nrun(\n suite(\n \"insertBuffer\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(12))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(15))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 10, 11, 12, 13, 14, 15, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(15);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(0, buffer2);\n\nrun(\n suite(\n \"insertBuffer at start\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(12))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(15))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(15);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(6, buffer2);\n\nrun(\n suite(\n \"insertBuffer at end\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(12))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(15))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(8);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(3, buffer2);\n\nrun(\n suite(\n \"insertBuffer with capacity change\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(12))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(18))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 10, 11, 12, 13, 14, 15, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(8);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(0, buffer2);\n\nrun(\n suite(\n \"insertBuffer at start with capacity change\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(12))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(18))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(8);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(6, buffer2);\n\nrun(\n suite(\n \"insertBuffer at end with capacity change\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(12))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(18))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(7);\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(0, buffer2);\n\nrun(\n suite(\n \"insertBuffer to empty buffer\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(6))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(7))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [10, 11, 12, 13, 14, 15]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nbuffer2 := B.Buffer<Nat>(10);\n\nfor (i in Iter.range(10, 15)) {\n buffer2.add(i)\n};\n\nbuffer.insertBuffer(0, buffer2);\n\nrun(\n suite(\n \"insertBuffer to empty buffer with capacity change\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(6))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(9))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [10, 11, 12, 13, 14, 15]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nbuffer.clear();\n\nrun(\n suite(\n \"clear\",\n [\n test(\n \"size\",\n buffer.size(),\n M.equals(T.nat(0))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nbuffer2 := B.clone(buffer);\n\nrun(\n suite(\n \"clone\",\n [\n test(\n \"size\",\n buffer2.size(),\n M.equals(T.nat(buffer.size()))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(buffer2.capacity()))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, B.toArray(buffer2)))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nvar size = 0;\n\nfor (element in buffer.vals()) {\n M.assertThat(element, M.equals(T.nat(size)));\n size += 1\n};\n\nrun(\n suite(\n \"vals\",\n [\n test(\n \"size\",\n size,\n M.equals(T.nat(7))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nrun(\n suite(\n \"array round trips\",\n [\n test(\n \"fromArray and toArray\",\n B.toArray<Nat>(B.fromArray<Nat>([0, 1, 2, 3])),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3]))\n ),\n test(\n \"fromVarArray\",\n B.toArray<Nat>(B.fromVarArray<Nat>([var 0, 1, 2, 3])),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nrun(\n suite(\n \"empty array round trips\",\n [\n test(\n \"fromArray and toArray\",\n B.toArray<Nat>(B.fromArray<Nat>([])),\n M.equals(T.array<Nat>(T.natTestable, []))\n ),\n test(\n \"fromVarArray\",\n B.toArray<Nat>(B.fromVarArray<Nat>([var])),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"iter round trips\",\n [\n test(\n \"fromIter and vals\",\n B.toArray(B.fromIter<Nat>(buffer.vals())),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5, 6]))\n ),\n test(\n \"empty\",\n B.toArray(B.fromIter<Nat>(B.Buffer<Nat>(2).vals())),\n M.equals(T.array<Nat>(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nB.trimToSize(buffer);\n\nrun(\n suite(\n \"trimToSize\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(7))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5, 6]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nB.trimToSize(buffer);\n\nrun(\n suite(\n \"trimToSize on empty\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(0))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nbuffer2 := B.map<Nat, Nat>(buffer, func x = x * 2);\n\nrun(\n suite(\n \"map\",\n [\n test(\n \"capacity\",\n buffer2.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer2),\n M.equals(T.array<Nat>(T.natTestable, [0, 2, 4, 6, 8, 10, 12]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(0);\n\nbuffer2 := B.map<Nat, Nat>(buffer, func x = x * 2);\n\nrun(\n suite(\n \"map empty\",\n [\n test(\n \"capacity\",\n buffer2.capacity(),\n M.equals(T.nat(0))\n ),\n test(\n \"elements\",\n B.toArray(buffer2),\n M.equals(T.array<Nat>(T.natTestable, []))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nvar sum = 0;\n\nB.iterate<Nat>(buffer, func x = sum += x);\n\nrun(\n suite(\n \"iterate\",\n [\n test(\n \"sum\",\n sum,\n M.equals(T.nat(21))\n ),\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 2, 3, 4, 5, 6]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nbuffer2 := B.chain<Nat, Nat>(buffer, func x = B.make<Nat> x);\n\nrun(\n suite(\n \"chain\",\n [\n test(\n \"elements\",\n B.toArray(buffer2),\n M.equals(T.array<Nat>(T.natTestable, B.toArray(buffer)))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nbuffer2 := B.mapFilter<Nat, Nat>(buffer, func x = if (x % 2 == 0) { ?x } else { null });\n\nrun(\n suite(\n \"mapFilter\",\n [\n test(\n \"capacity\",\n buffer2.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer2),\n M.equals(T.array<Nat>(T.natTestable, [0, 2, 4, 6]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nbuffer2 := B.mapEntries<Nat, Nat>(buffer, func(i, x) = i * x);\n\nrun(\n suite(\n \"mapEntries\",\n [\n test(\n \"capacity\",\n buffer2.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer2),\n M.equals(T.array<Nat>(T.natTestable, [0, 1, 4, 9, 16, 25, 36]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nvar bufferResult = B.mapResult<Nat, Nat, Text>(buffer, func x = #ok x);\n\nrun(\n suite(\n \"mapResult success\",\n [\n test(\n \"return value\",\n #ok buffer,\n M.equals(T.result<B.Buffer<Nat>, Text>(NatBufferTestable, T.textTestable, bufferResult))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nbufferResult := B.mapResult<Nat, Nat, Text>(\n buffer,\n func x = if (x == 4) { #err \"error\" } else { #ok x }\n);\n\nrun(\n suite(\n \"mapResult failure\",\n [\n test(\n \"return value\",\n #err \"error\",\n M.equals(T.result<B.Buffer<Nat>, Text>(NatBufferTestable, T.textTestable, bufferResult))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"foldLeft\",\n [\n test(\n \"return value\",\n B.foldLeft<Text, Nat>(buffer, \"\", func(acc, x) = acc # Nat.toText(x)),\n M.equals(T.text(\"0123456\"))\n ),\n test(\n \"return value empty\",\n B.foldLeft<Text, Nat>(B.Buffer<Nat>(4), \"\", func(acc, x) = acc # Nat.toText(x)),\n M.equals(T.text(\"\"))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"foldRight\",\n [\n test(\n \"return value\",\n B.foldRight<Nat, Text>(buffer, \"\", func(x, acc) = acc # Nat.toText(x)),\n M.equals(T.text(\"6543210\"))\n ),\n test(\n \"return value empty\",\n B.foldRight<Nat, Text>(B.Buffer<Nat>(4), \"\", func(x, acc) = acc # Nat.toText(x)),\n M.equals(T.text(\"\"))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"forAll\",\n [\n test(\n \"true\",\n B.forAll<Nat>(buffer, func x = x >= 0),\n M.equals(T.bool(true))\n ),\n test(\n \"false\",\n B.forAll<Nat>(buffer, func x = x % 2 == 0),\n M.equals(T.bool(false))\n ),\n test(\n \"default\",\n B.forAll<Nat>(B.Buffer<Nat>(2), func _ = false),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nrun(\n suite(\n \"forSome\",\n [\n test(\n \"true\",\n B.forSome<Nat>(buffer, func x = x % 2 == 0),\n M.equals(T.bool(true))\n ),\n test(\n \"false\",\n B.forSome<Nat>(buffer, func x = x < 0),\n M.equals(T.bool(false))\n ),\n test(\n \"default\",\n B.forSome<Nat>(B.Buffer<Nat>(2), func _ = false),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nrun(\n suite(\n \"forNone\",\n [\n test(\n \"true\",\n B.forNone<Nat>(buffer, func x = x < 0),\n M.equals(T.bool(true))\n ),\n test(\n \"false\",\n B.forNone<Nat>(buffer, func x = x % 2 != 0),\n M.equals(T.bool(false))\n ),\n test(\n \"default\",\n B.forNone<Nat>(B.Buffer<Nat>(2), func _ = true),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.make<Nat>(1);\n\nrun(\n suite(\n \"make\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [1]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"contains\",\n [\n test(\n \"true\",\n B.contains<Nat>(buffer, 2, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"true\",\n B.contains<Nat>(buffer, 9, Nat.equal),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\n\nrun(\n suite(\n \"contains empty\",\n [\n test(\n \"true\",\n B.contains<Nat>(buffer, 2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"true\",\n B.contains<Nat>(buffer, 9, Nat.equal),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\n\nbuffer.add(2);\nbuffer.add(1);\nbuffer.add(10);\nbuffer.add(1);\nbuffer.add(0);\nbuffer.add(3);\n\nrun(\n suite(\n \"max\",\n [\n test(\n \"return value\",\n B.max<Nat>(buffer, Nat.compare),\n M.equals(T.optional(T.natTestable, ?10))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\n\nbuffer.add(2);\nbuffer.add(1);\nbuffer.add(10);\nbuffer.add(1);\nbuffer.add(0);\nbuffer.add(3);\nbuffer.add(0);\n\nrun(\n suite(\n \"min\",\n [\n test(\n \"return value\",\n B.min<Nat>(buffer, Nat.compare),\n M.equals(T.optional(T.natTestable, ?0))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\nbuffer.add(2);\n\nrun(\n suite(\n \"isEmpty\",\n [\n test(\n \"true\",\n B.isEmpty(B.Buffer<Nat>(2)),\n M.equals(T.bool(true))\n ),\n test(\n \"false\",\n B.isEmpty(buffer),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\n\nbuffer.add(2);\nbuffer.add(1);\nbuffer.add(10);\nbuffer.add(1);\nbuffer.add(0);\nbuffer.add(3);\nbuffer.add(0);\n\nB.removeDuplicates<Nat>(buffer, Nat.compare);\n\nrun(\n suite(\n \"removeDuplicates\",\n [\n test(\n \"elements (stable ordering)\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [2, 1, 10, 0, 3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\n\nB.removeDuplicates<Nat>(buffer, Nat.compare);\n\nrun(\n suite(\n \"removeDuplicates empty\",\n [\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(2)\n};\n\nB.removeDuplicates<Nat>(buffer, Nat.compare);\n\nrun(\n suite(\n \"removeDuplicates repeat singleton\",\n [\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [2]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"hash\",\n [\n test(\n \"empty buffer\",\n Nat32.toNat(B.hash<Nat>(B.Buffer<Nat>(8), Hash.hash)),\n M.equals(T.nat(0))\n ),\n test(\n \"non-empty buffer\",\n Nat32.toNat(B.hash<Nat>(buffer, Hash.hash)),\n M.equals(T.nat(3365238326))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"toText\",\n [\n test(\n \"empty buffer\",\n B.toText<Nat>(B.Buffer<Nat>(3), Nat.toText),\n M.equals(T.text(\"[]\"))\n ),\n test(\n \"singleton buffer\",\n B.toText<Nat>(B.make<Nat>(3), Nat.toText),\n M.equals(T.text(\"[3]\"))\n ),\n test(\n \"non-empty buffer\",\n B.toText<Nat>(buffer, Nat.toText),\n M.equals(T.text(\"[0, 1, 2, 3, 4, 5]\"))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 2)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"equal\",\n [\n test(\n \"empty buffers\",\n B.equal<Nat>(B.Buffer<Nat>(3), B.Buffer<Nat>(2), Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"non-empty buffers\",\n B.equal<Nat>(buffer, B.clone(buffer), Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"non-empty and empty buffers\",\n B.equal<Nat>(buffer, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"non-empty buffers mismatching lengths\",\n B.equal<Nat>(buffer, buffer2, Nat.equal),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer2 := B.Buffer<Nat>(3);\n\nfor (i in Iter.range(0, 2)) {\n buffer.add(i)\n};\n\nvar buffer3 = B.Buffer<Nat>(3);\n\nfor (i in Iter.range(2, 5)) {\n buffer3.add(i)\n};\n\nrun(\n suite(\n \"compare\",\n [\n test(\n \"empty buffers\",\n B.compare<Nat>(B.Buffer<Nat>(3), B.Buffer<Nat>(2), Nat.compare),\n M.equals(OrderTestable(#equal))\n ),\n test(\n \"non-empty buffers equal\",\n B.compare<Nat>(buffer, B.clone(buffer), Nat.compare),\n M.equals(OrderTestable(#equal))\n ),\n test(\n \"non-empty and empty buffers\",\n B.compare<Nat>(buffer, B.Buffer<Nat>(3), Nat.compare),\n M.equals(OrderTestable(#greater))\n ),\n test(\n \"non-empty buffers mismatching lengths\",\n B.compare<Nat>(buffer, buffer2, Nat.compare),\n M.equals(OrderTestable(#greater))\n ),\n test(\n \"non-empty buffers lexicographic difference\",\n B.compare<Nat>(buffer, buffer3, Nat.compare),\n M.equals(OrderTestable(#less))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nvar nestedBuffer = B.Buffer<B.Buffer<Nat>>(3);\nfor (i in Iter.range(0, 4)) {\n let innerBuffer = B.Buffer<Nat>(2);\n for (j in if (i % 2 == 0) { Iter.range(0, 4) } else { Iter.range(0, 3) }) {\n innerBuffer.add(j)\n };\n nestedBuffer.add(innerBuffer)\n};\nnestedBuffer.add(B.Buffer<Nat>(2));\n\nbuffer := B.flatten<Nat>(nestedBuffer);\n\nrun(\n suite(\n \"flatten\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(45))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 3, 4]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nnestedBuffer := B.Buffer<B.Buffer<Nat>>(3);\nfor (i in Iter.range(0, 4)) {\n nestedBuffer.add(B.Buffer<Nat>(2))\n};\n\nbuffer := B.flatten<Nat>(nestedBuffer);\n\nrun(\n suite(\n \"flatten all empty inner buffers\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nnestedBuffer := B.Buffer<B.Buffer<Nat>>(3);\nbuffer := B.flatten<Nat>(nestedBuffer);\n\nrun(\n suite(\n \"flatten empty outer buffer\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(0))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 7)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\n\nfor (i in Iter.range(0, 6)) {\n buffer2.add(i)\n};\n\nbuffer3.clear();\n\nvar buffer4 = B.make<Nat>(3);\n\nB.reverse<Nat>(buffer);\nB.reverse<Nat>(buffer2);\nB.reverse<Nat>(buffer3);\nB.reverse<Nat>(buffer4);\n\nrun(\n suite(\n \"reverse\",\n [\n test(\n \"even elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [7, 6, 5, 4, 3, 2, 1, 0]))\n ),\n test(\n \"odd elements\",\n B.toArray(buffer2),\n M.equals(T.array(T.natTestable, [6, 5, 4, 3, 2, 1, 0]))\n ),\n test(\n \"empty\",\n B.toArray(buffer3),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n ),\n test(\n \"singleton\",\n B.toArray(buffer4),\n M.equals(T.array(T.natTestable, [3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer.clear();\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nvar partition = B.partition<Nat>(buffer, func x = x % 2 == 0);\nbuffer2 := partition.0;\nbuffer3 := partition.1;\n\nrun(\n suite(\n \"partition\",\n [\n test(\n \"capacity of true buffer\",\n buffer2.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements of true buffer\",\n B.toArray(buffer2),\n M.equals(T.array(T.natTestable, [0, 2, 4]))\n ),\n test(\n \"capacity of false buffer\",\n buffer3.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements of false buffer\",\n B.toArray(buffer3),\n M.equals(T.array(T.natTestable, [1, 3, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer.clear();\nfor (i in Iter.range(0, 3)) {\n buffer.add(i)\n};\n\nfor (i in Iter.range(10, 13)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\nfor (i in Iter.range(2, 5)) {\n buffer2.add(i)\n};\nfor (i in Iter.range(13, 15)) {\n buffer2.add(i)\n};\n\nbuffer := B.merge<Nat>(buffer, buffer2, Nat.compare);\n\nrun(\n suite(\n \"merge\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(23))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [0, 1, 2, 2, 3, 3, 4, 5, 10, 11, 12, 13, 13, 14, 15]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer.clear();\nfor (i in Iter.range(0, 3)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\n\nbuffer := B.merge<Nat>(buffer, buffer2, Nat.compare);\n\nrun(\n suite(\n \"merge with empty\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [0, 1, 2, 3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\n\nbuffer.clear();\nbuffer2.clear();\n\nbuffer := B.merge<Nat>(buffer, buffer2, Nat.compare);\n\nrun(\n suite(\n \"merge two empty\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nbuffer.add(0);\nbuffer.add(2);\nbuffer.add(1);\nbuffer.add(1);\nbuffer.add(5);\nbuffer.add(4);\n\nbuffer.sort(Nat.compare);\n\nrun(\n suite(\n \"sort even\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [0, 1, 1, 2, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nbuffer.add(0);\nbuffer.add(2);\nbuffer.add(1);\nbuffer.add(1);\nbuffer.add(5);\n\nbuffer.sort(Nat.compare);\n\nrun(\n suite(\n \"sort odd\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [0, 1, 1, 2, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nbuffer.sort(Nat.compare);\n\nrun(\n suite(\n \"sort empty\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\nbuffer.add(2);\n\nbuffer.sort(Nat.compare);\n\nrun(\n suite(\n \"sort singleton\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [2] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\npartition := B.split<Nat>(buffer, 2);\nbuffer2 := partition.0;\nbuffer3 := partition.1;\n\nrun(\n suite(\n \"split\",\n [\n test(\n \"capacity prefix\",\n buffer2.capacity(),\n M.equals(T.nat(3))\n ),\n test(\n \"elements prefix\",\n B.toArray(buffer2),\n M.equals(T.array(T.natTestable, [0, 1]))\n ),\n test(\n \"capacity suffix\",\n buffer3.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements suffix\",\n B.toArray(buffer3),\n M.equals(T.array(T.natTestable, [2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\npartition := B.split<Nat>(buffer, 0);\nbuffer2 := partition.0;\nbuffer3 := partition.1;\n\nrun(\n suite(\n \"split at index 0\",\n [\n test(\n \"capacity prefix\",\n buffer2.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements prefix\",\n B.toArray(buffer2),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n ),\n test(\n \"capacity suffix\",\n buffer3.capacity(),\n M.equals(T.nat(9))\n ),\n test(\n \"elements suffix\",\n B.toArray(buffer3),\n M.equals(T.array(T.natTestable, [0, 1, 2, 3, 4, 5]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\npartition := B.split<Nat>(buffer, 6);\nbuffer2 := partition.0;\nbuffer3 := partition.1;\n\nrun(\n suite(\n \"split at last index\",\n [\n test(\n \"capacity prefix\",\n buffer2.capacity(),\n M.equals(T.nat(9))\n ),\n test(\n \"elements prefix\",\n B.toArray(buffer2),\n M.equals(T.array(T.natTestable, [0, 1, 2, 3, 4, 5]))\n ),\n test(\n \"capacity suffix\",\n buffer3.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements suffix\",\n B.toArray(buffer3),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\nbuffer2.clear();\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\nfor (i in Iter.range(0, 3)) {\n buffer2.add(i)\n};\n\nvar bufferPairs = B.zip<Nat, Nat>(buffer, buffer2);\n\nrun(\n suite(\n \"zip\",\n [\n test(\n \"capacity\",\n bufferPairs.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements\",\n B.toArray(bufferPairs),\n M.equals(T.array(T.tuple2Testable(T.natTestable, T.natTestable), [(0, 0), (1, 1), (2, 2), (3, 3)]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\nbuffer2.clear();\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbufferPairs := B.zip<Nat, Nat>(buffer, buffer2);\n\nrun(\n suite(\n \"zip empty\",\n [\n test(\n \"capacity\",\n bufferPairs.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(bufferPairs),\n M.equals(T.array(T.tuple2Testable(T.natTestable, T.natTestable), [] : [(Nat, Nat)]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\nbuffer2.clear();\n\nbufferPairs := B.zip<Nat, Nat>(buffer, buffer2);\n\nrun(\n suite(\n \"zip both empty\",\n [\n test(\n \"capacity\",\n bufferPairs.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(bufferPairs),\n M.equals(T.array(T.tuple2Testable(T.natTestable, T.natTestable), [] : [(Nat, Nat)]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\nbuffer2.clear();\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\nfor (i in Iter.range(0, 3)) {\n buffer2.add(i)\n};\n\nbuffer3 := B.zipWith<Nat, Nat, Nat>(buffer, buffer2, Nat.add);\n\nrun(\n suite(\n \"zipWith\",\n [\n test(\n \"capacity\",\n buffer3.capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"elements\",\n B.toArray(buffer3),\n M.equals(T.array(T.natTestable, [0, 2, 4, 6]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\nbuffer2.clear();\n\nfor (i in Iter.range(0, 5)) {\n buffer.add(i)\n};\n\nbuffer3 := B.zipWith<Nat, Nat, Nat>(buffer, buffer2, Nat.add);\n\nrun(\n suite(\n \"zipWithEmpty\",\n [\n test(\n \"capacity\",\n buffer3.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(buffer3),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 8)) {\n buffer.add(i)\n};\n\nvar chunks = B.chunk<Nat>(buffer, 2);\n\nrun(\n suite(\n \"chunk\",\n [\n test(\n \"num chunks\",\n chunks.size(),\n M.equals(T.nat(5))\n ),\n test(\n \"chunk 0 capacity\",\n chunks.get(0).capacity(),\n M.equals(T.nat(3))\n ),\n test(\n \"chunk 0 elements\",\n B.toArray(chunks.get(0)),\n M.equals(T.array(T.natTestable, [0, 1]))\n ),\n test(\n \"chunk 2 capacity\",\n chunks.get(2).capacity(),\n M.equals(T.nat(3))\n ),\n test(\n \"chunk 2 elements\",\n B.toArray(chunks.get(2)),\n M.equals(T.array(T.natTestable, [4, 5]))\n ),\n test(\n \"chunk 4 capacity\",\n chunks.get(4).capacity(),\n M.equals(T.nat(3))\n ),\n test(\n \"chunk 4 elements\",\n B.toArray(chunks.get(4)),\n M.equals(T.array(T.natTestable, [8]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nchunks := B.chunk<Nat>(buffer, 3);\n\nrun(\n suite(\n \"chunk empty\",\n [\n test(\n \"num chunks\",\n chunks.size(),\n M.equals(T.nat(0))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nchunks := B.chunk<Nat>(buffer, 10);\n\nrun(\n suite(\n \"chunk larger than buffer\",\n [\n test(\n \"num chunks\",\n chunks.size(),\n M.equals(T.nat(1))\n ),\n test(\n \"chunk 0 elements\",\n B.toArray(chunks.get(0)),\n M.equals(T.array(T.natTestable, [0, 1, 2, 3, 4]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nbuffer.add(2);\nbuffer.add(2);\nbuffer.add(2);\nbuffer.add(1);\nbuffer.add(0);\nbuffer.add(0);\nbuffer.add(2);\nbuffer.add(1);\nbuffer.add(1);\n\nvar groups = B.groupBy<Nat>(buffer, Nat.equal);\n\nrun(\n suite(\n \"groupBy\",\n [\n test(\n \"num groups\",\n groups.size(),\n M.equals(T.nat(5))\n ),\n test(\n \"group 0 capacity\",\n groups.get(0).capacity(),\n M.equals(T.nat(9))\n ),\n test(\n \"group 0 elements\",\n B.toArray(groups.get(0)),\n M.equals(T.array(T.natTestable, [2, 2, 2]))\n ),\n test(\n \"group 1 capacity\",\n groups.get(1).capacity(),\n M.equals(T.nat(6))\n ),\n test(\n \"group 1 elements\",\n B.toArray(groups.get(1)),\n M.equals(T.array(T.natTestable, [1]))\n ),\n test(\n \"group 4 capacity\",\n groups.get(4).capacity(),\n M.equals(T.nat(2))\n ),\n test(\n \"group 4 elements\",\n B.toArray(groups.get(4)),\n M.equals(T.array(T.natTestable, [1, 1]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\ngroups := B.groupBy<Nat>(buffer, Nat.equal);\n\nrun(\n suite(\n \"groupBy clear\",\n [\n test(\n \"num groups\",\n groups.size(),\n M.equals(T.nat(0))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(0)\n};\n\ngroups := B.groupBy<Nat>(buffer, Nat.equal);\n\nrun(\n suite(\n \"groupBy clear\",\n [\n test(\n \"num groups\",\n groups.size(),\n M.equals(T.nat(1))\n ),\n test(\n \"group 0 elements\",\n B.toArray(groups.get(0)),\n M.equals(T.array(T.natTestable, [0, 0, 0, 0, 0]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer := B.prefix<Nat>(buffer, 3);\n\nrun(\n suite(\n \"prefix\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(5))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [0, 1, 2]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nbuffer := B.prefix<Nat>(buffer, 0);\n\nrun(\n suite(\n \"prefix of empty\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(1))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer := B.prefix<Nat>(buffer, 5);\n\nrun(\n suite(\n \"trivial prefix\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(8))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [0, 1, 2, 3, 4]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\n\nfor (i in Iter.range(0, 2)) {\n buffer2.add(i)\n};\n\nbuffer3.clear();\n\nbuffer3.add(2);\nbuffer3.add(1);\nbuffer3.add(0);\n\nrun(\n suite(\n \"isPrefixOf\",\n [\n test(\n \"normal prefix\",\n B.isPrefixOf<Nat>(buffer2, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"identical buffers\",\n B.isPrefixOf<Nat>(buffer, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"one empty buffer\",\n B.isPrefixOf<Nat>(B.Buffer<Nat>(3), buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"not prefix\",\n B.isPrefixOf<Nat>(buffer3, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not prefix from length\",\n B.isPrefixOf<Nat>(buffer, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not prefix of empty\",\n B.isPrefixOf<Nat>(buffer, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"empty prefix of empty\",\n B.isPrefixOf<Nat>(B.Buffer<Nat>(4), B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\n\nfor (i in Iter.range(0, 2)) {\n buffer2.add(i)\n};\n\nbuffer3.clear();\n\nbuffer3.add(2);\nbuffer3.add(1);\nbuffer3.add(0);\n\nrun(\n suite(\n \"isStrictPrefixOf\",\n [\n test(\n \"normal prefix\",\n B.isStrictPrefixOf<Nat>(buffer2, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"identical buffers\",\n B.isStrictPrefixOf<Nat>(buffer, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"one empty buffer\",\n B.isStrictPrefixOf<Nat>(B.Buffer<Nat>(3), buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"not prefix\",\n B.isStrictPrefixOf<Nat>(buffer3, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not prefix from length\",\n B.isStrictPrefixOf<Nat>(buffer, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not prefix of empty\",\n B.isStrictPrefixOf<Nat>(buffer, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"empty prefix of empty\",\n B.isStrictPrefixOf<Nat>(B.Buffer<Nat>(4), B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer := B.subBuffer<Nat>(buffer, 1, 3);\n\nrun(\n suite(\n \"subBuffer\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(5))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [1, 2, 3]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"subBuffer edge cases\",\n [\n test(\n \"prefix\",\n B.prefix(buffer, 3),\n M.equals({ { item = B.subBuffer(buffer, 0, 3) } and NatBufferTestable })\n ),\n test(\n \"suffix\",\n B.suffix(buffer, 3),\n M.equals({ { item = B.subBuffer(buffer, 2, 3) } and NatBufferTestable })\n ),\n test(\n \"empty\",\n B.toArray(B.subBuffer(buffer, 2, 0)),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n ),\n test(\n \"trivial\",\n B.subBuffer(buffer, 0, buffer.size()),\n M.equals({ { item = buffer } and NatBufferTestable })\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\n\nfor (i in Iter.range(0, 2)) {\n buffer2.add(i)\n};\n\nbuffer3.clear();\n\nfor (i in Iter.range(1, 3)) {\n buffer3.add(i)\n};\n\nrun(\n suite(\n \"isSubBufferOf\",\n [\n test(\n \"normal subBuffer\",\n B.isSubBufferOf<Nat>(buffer3, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"prefix\",\n B.isSubBufferOf<Nat>(buffer2, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"identical buffers\",\n B.isSubBufferOf<Nat>(buffer, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"one empty buffer\",\n B.isSubBufferOf<Nat>(B.Buffer<Nat>(3), buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"not subBuffer\",\n B.isSubBufferOf<Nat>(buffer3, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not subBuffer from length\",\n B.isSubBufferOf<Nat>(buffer, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not subBuffer of empty\",\n B.isSubBufferOf<Nat>(buffer, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"empty subBuffer of empty\",\n B.isSubBufferOf<Nat>(B.Buffer<Nat>(4), B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\n\nfor (i in Iter.range(0, 2)) {\n buffer2.add(i)\n};\n\nbuffer3.clear();\n\nfor (i in Iter.range(1, 3)) {\n buffer3.add(i)\n};\n\nbuffer4 := B.Buffer<Nat>(4);\n\nfor (i in Iter.range(3, 4)) {\n buffer4.add(i)\n};\n\nrun(\n suite(\n \"isStrictSubBufferOf\",\n [\n test(\n \"normal strict subBuffer\",\n B.isStrictSubBufferOf<Nat>(buffer3, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"prefix\",\n B.isStrictSubBufferOf<Nat>(buffer2, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"suffix\",\n B.isStrictSubBufferOf<Nat>(buffer4, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"identical buffers\",\n B.isStrictSubBufferOf<Nat>(buffer, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"one empty buffer\",\n B.isStrictSubBufferOf<Nat>(B.Buffer<Nat>(3), buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"not subBuffer\",\n B.isStrictSubBufferOf<Nat>(buffer3, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not subBuffer from length\",\n B.isStrictSubBufferOf<Nat>(buffer, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not subBuffer of empty\",\n B.isStrictSubBufferOf<Nat>(buffer, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"empty not strict subBuffer of empty\",\n B.isStrictSubBufferOf<Nat>(B.Buffer<Nat>(4), B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer := B.suffix<Nat>(buffer, 3);\n\nrun(\n suite(\n \"suffix\",\n [\n test(\n \"capacity\",\n buffer.capacity(),\n M.equals(T.nat(5))\n ),\n test(\n \"elements\",\n B.toArray(buffer),\n M.equals(T.array(T.natTestable, [2, 3, 4]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"suffix edge cases\",\n [\n test(\n \"empty\",\n B.toArray(B.prefix(buffer, 0)),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n ),\n test(\n \"trivial\",\n B.prefix(buffer, buffer.size()),\n M.equals({ { item = buffer } and NatBufferTestable })\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\nfor (i in Iter.range(3, 4)) {\n buffer2.add(i)\n};\n\nbuffer3.clear();\n\nbuffer3.add(2);\nbuffer3.add(1);\nbuffer3.add(0);\n\nrun(\n suite(\n \"isSuffixOf\",\n [\n test(\n \"normal suffix\",\n B.isSuffixOf<Nat>(buffer2, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"identical buffers\",\n B.isSuffixOf<Nat>(buffer, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"one empty buffer\",\n B.isSuffixOf<Nat>(B.Buffer<Nat>(3), buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"not suffix\",\n B.isSuffixOf<Nat>(buffer3, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not suffix from length\",\n B.isSuffixOf<Nat>(buffer, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not suffix of empty\",\n B.isSuffixOf<Nat>(buffer, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"empty suffix of empty\",\n B.isSuffixOf<Nat>(B.Buffer<Nat>(4), B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(true))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nbuffer2.clear();\nfor (i in Iter.range(3, 4)) {\n buffer2.add(i)\n};\n\nbuffer3.clear();\n\nbuffer3.add(2);\nbuffer3.add(1);\nbuffer3.add(0);\n\nrun(\n suite(\n \"isStrictSuffixOf\",\n [\n test(\n \"normal suffix\",\n B.isStrictSuffixOf<Nat>(buffer2, buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"identical buffers\",\n B.isStrictSuffixOf<Nat>(buffer, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"one empty buffer\",\n B.isStrictSuffixOf<Nat>(B.Buffer<Nat>(3), buffer, Nat.equal),\n M.equals(T.bool(true))\n ),\n test(\n \"not suffix\",\n B.isStrictSuffixOf<Nat>(buffer3, buffer, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not suffix from length\",\n B.isStrictSuffixOf<Nat>(buffer, buffer2, Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"not suffix of empty\",\n B.isStrictSuffixOf<Nat>(buffer, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n ),\n test(\n \"empty suffix of empty\",\n B.isStrictSuffixOf<Nat>(B.Buffer<Nat>(4), B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.bool(false))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"takeWhile\",\n [\n test(\n \"normal case\",\n B.toArray(B.takeWhile<Nat>(buffer, func x = x < 3)),\n M.equals(T.array(T.natTestable, [0, 1, 2]))\n ),\n test(\n \"empty\",\n B.toArray(B.takeWhile<Nat>(B.Buffer<Nat>(3), func x = x < 3)),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 4)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"dropWhile\",\n [\n test(\n \"normal case\",\n B.toArray(B.dropWhile<Nat>(buffer, func x = x < 3)),\n M.equals(T.array(T.natTestable, [3, 4]))\n ),\n test(\n \"empty\",\n B.toArray(B.dropWhile<Nat>(B.Buffer<Nat>(3), func x = x < 3)),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n ),\n test(\n \"drop all\",\n B.toArray(B.dropWhile<Nat>(buffer, func _ = true)),\n M.equals(T.array(T.natTestable, [] : [Nat]))\n ),\n test(\n \"drop none\",\n B.toArray(B.dropWhile<Nat>(buffer, func _ = false)),\n M.equals(T.array(T.natTestable, [0, 1, 2, 3, 4]))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(1, 6)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"binarySearch\",\n [\n test(\n \"find in middle\",\n B.binarySearch<Nat>(2, buffer, Nat.compare),\n M.equals(T.optional(T.natTestable, ?1))\n ),\n test(\n \"find first\",\n B.binarySearch<Nat>(1, buffer, Nat.compare),\n M.equals(T.optional(T.natTestable, ?0))\n ),\n test(\n \"find last\",\n B.binarySearch<Nat>(6, buffer, Nat.compare),\n M.equals(T.optional(T.natTestable, ?5))\n ),\n test(\n \"not found to the right\",\n B.binarySearch<Nat>(10, buffer, Nat.compare),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"not found to the left\",\n B.binarySearch<Nat>(0, buffer, Nat.compare),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nfor (i in Iter.range(0, 6)) {\n buffer.add(i)\n};\n\nrun(\n suite(\n \"indexOf\",\n [\n test(\n \"find in middle\",\n B.indexOf<Nat>(2, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?2))\n ),\n test(\n \"find first\",\n B.indexOf<Nat>(0, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?0))\n ),\n test(\n \"find last\",\n B.indexOf<Nat>(6, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?6))\n ),\n test(\n \"not found\",\n B.indexOf<Nat>(10, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"empty\",\n B.indexOf<Nat>(100, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nbuffer.add(2); // 0\nbuffer.add(2); // 1\nbuffer.add(1); // 2\nbuffer.add(10); // 3\nbuffer.add(1); // 4\nbuffer.add(0); // 5\nbuffer.add(10); // 6\nbuffer.add(3); // 7\nbuffer.add(0); // 8\n\nrun(\n suite(\n \"lastIndexOf\",\n [\n test(\n \"find in middle\",\n B.lastIndexOf<Nat>(10, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?6))\n ),\n test(\n \"find only\",\n B.lastIndexOf<Nat>(3, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?7))\n ),\n test(\n \"find last\",\n B.lastIndexOf<Nat>(0, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?8))\n ),\n test(\n \"not found\",\n B.lastIndexOf<Nat>(100, buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"empty\",\n B.lastIndexOf<Nat>(100, B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n )\n ]\n )\n);\n\n/* --------------------------------------- */\nbuffer.clear();\n\nbuffer.add(2); // 0\nbuffer.add(2); // 1\nbuffer.add(1); // 2\nbuffer.add(10); // 3\nbuffer.add(1); // 4\nbuffer.add(10); // 5\nbuffer.add(3); // 6\nbuffer.add(0); // 7\n\nrun(\n suite(\n \"indexOfBuffer\",\n [\n test(\n \"find in middle\",\n B.indexOfBuffer<Nat>(B.fromArray<Nat>([1, 10, 1]), buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?2))\n ),\n test(\n \"find first\",\n B.indexOfBuffer<Nat>(B.fromArray<Nat>([2, 2, 1, 10]), buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?0))\n ),\n test(\n \"find last\",\n B.indexOfBuffer<Nat>(B.fromArray<Nat>([0]), buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, ?7))\n ),\n test(\n \"not found\",\n B.indexOfBuffer<Nat>(B.fromArray<Nat>([99, 100, 1]), buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"search for empty buffer\",\n B.indexOfBuffer<Nat>(B.fromArray<Nat>([]), buffer, Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"search through empty buffer\",\n B.indexOfBuffer<Nat>(B.fromArray<Nat>([1, 2, 3]), B.Buffer<Nat>(2), Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n ),\n test(\n \"search for empty in empty\",\n B.indexOfBuffer<Nat>(B.Buffer<Nat>(2), B.Buffer<Nat>(3), Nat.equal),\n M.equals(T.optional(T.natTestable, null : ?Nat))\n )\n ]\n )\n)\n"},"heapTest.mo":{"content":"import H \"mo:base/Heap\";\nimport I \"mo:base/Iter\";\nimport O \"mo:base/Option\";\nimport Int \"mo:base/Int\";\n\nlet order = Int.compare;\n\ndo {\n var pq = H.Heap<Int>(order);\n for (i in I.revRange(100, 0)) {\n pq.put(i);\n let x = pq.peekMin();\n assert (O.unwrap(x) == i)\n };\n for (i in I.range(0, 100)) {\n pq.put(i);\n let x = pq.peekMin();\n assert (O.unwrap(x) == 0)\n };\n for (i in I.range(0, 100)) {\n pq.deleteMin();\n let x = pq.peekMin();\n pq.deleteMin();\n assert (O.unwrap(x) == i)\n };\n O.assertNull(pq.peekMin())\n};\n\n// fromIter\ndo {\n do {\n let iter = [5, 10, 9, 7, 3, 8, 1, 0, 2, 4, 6].vals();\n let pq = H.fromIter<Int>(iter, order);\n for (i in I.range(0, 10)) {\n let x = pq.peekMin();\n assert (O.unwrap(x) == i);\n pq.deleteMin()\n };\n O.assertNull(pq.peekMin())\n };\n\n do {\n let pq = H.fromIter<Int>([].vals(), order);\n O.assertNull(pq.peekMin())\n };\n\n do {\n let pq = H.fromIter<Int>([100].vals(), order);\n assert (O.unwrap(pq.peekMin()) == 100)\n }\n}\n"}}}