diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a559c82bb1..247438179c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,6 +132,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 + # Default is too slow, 256 + - name: Increase file descriptors limit (macOS only) + if: runner.os == 'macOS' + run: sudo launchctl limit maxfiles 6000 10000 + + - name: Increase max user process (macOS only) + if: runner.os == 'macOS' + run: sudo launchctl limit maxproc 5000 8000 + - name: Use Node.js uses: actions/setup-node@v4 with: @@ -317,6 +326,12 @@ jobs: - name: Run tests run: node scripts/test.js -all + - name: Docstrins tests + if: runner.os == 'macOS' + env: + UV_THREADPOOL_SIZE: 8 + run: node tests/docstrings_examples/DocTest.res.mjs --ignore-runtime-tests "Array.toReversed, Array.toSorted, Promise.withResolvers, Set.union, Set.isSupersetOf, Set.isSubsetOf, Set.isDisjointFrom, Set.intersection, Set.symmetricDifference, Set.difference" + - name: Check for diffs in tests folder run: git diff --ignore-cr-at-eol --exit-code tests diff --git a/biome.json b/biome.json index 44dd98952b..de13644025 100644 --- a/biome.json +++ b/biome.json @@ -25,6 +25,7 @@ "tests/tests/**", "tests/tools_tests/**", "tests/analysis_tests/**", + "tests/docstrings_examples/**", "analysis/examples/**", "analysis/reanalyze/examples/**", "lib/**", diff --git a/lib/es6/Pervasives.js b/lib/es6/Pervasives.js index ee989cf955..5c493d7ea9 100644 --- a/lib/es6/Pervasives.js +++ b/lib/es6/Pervasives.js @@ -1,6 +1,7 @@ import * as $$Error from "./Error.js"; +import * as Primitive_object from "./Primitive_object.js"; import * as Primitive_exceptions from "./Primitive_exceptions.js"; function failwith(s) { @@ -116,6 +117,21 @@ function $at(l1, l2) { } } +function assertEqual(a, b) { + if (!Primitive_object.notequal(a, b)) { + return; + } + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "Pervasives.res", + 596, + 4 + ], + Error: new Error() + }; +} + let max_int = 2147483647; let infinity = Infinity; @@ -151,5 +167,6 @@ export { int_of_string_opt, $at, panic, + assertEqual, } /* No side effect */ diff --git a/lib/js/Pervasives.js b/lib/js/Pervasives.js index fa6d5f7e68..35d21521a1 100644 --- a/lib/js/Pervasives.js +++ b/lib/js/Pervasives.js @@ -1,6 +1,7 @@ 'use strict'; let $$Error = require("./Error.js"); +let Primitive_object = require("./Primitive_object.js"); let Primitive_exceptions = require("./Primitive_exceptions.js"); function failwith(s) { @@ -116,6 +117,21 @@ function $at(l1, l2) { } } +function assertEqual(a, b) { + if (!Primitive_object.notequal(a, b)) { + return; + } + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "Pervasives.res", + 596, + 4 + ], + Error: new Error() + }; +} + let max_int = 2147483647; let infinity = Infinity; @@ -150,4 +166,5 @@ exports.bool_of_string_opt = bool_of_string_opt; exports.int_of_string_opt = int_of_string_opt; exports.$at = $at; exports.panic = panic; +exports.assertEqual = assertEqual; /* No side effect */ diff --git a/runtime/Array.resi b/runtime/Array.resi index 8b57906b27..6fa12159e6 100644 --- a/runtime/Array.resi +++ b/runtime/Array.resi @@ -1,14 +1,17 @@ /** - `fromIterator(iterator)` +`fromIterator(iterator)` - Creates an array from the provided `iterator` +Creates an array from the provided `iterator` - ```res example - let map = Map.fromArray([("foo", 1), ("bar", 2)]) +## Examples - Array.fromIterator(map->Map.values) // [1, 2] - ``` - */ +```rescript +Map.fromArray([("foo", 1), ("bar", 2)]) +->Map.values +->Array.fromIterator +->assertEqual([1, 2]) +``` +*/ @val external fromIterator: Iterator.t<'a> => array<'a> = "Array.from" @@ -20,24 +23,31 @@ external fromIterator: Iterator.t<'a> => array<'a> = "Array.from" external fromArrayLikeWithMap: (Js.Array2.array_like<'a>, 'a => 'b) => array<'b> = "Array.from" /** - `make(~length, init)` +`make(~length, init)` + +Creates an array of length `length` initialized with the value of `init`. - Creates an array of length `length` initialized with the value of `init`. +## Examples - ```res example - Array.make(~length=3, #apple) == [#apple, #apple, #apple] - ``` +```rescript +Array.make(~length=3, #apple)->assertEqual([#apple, #apple, #apple]) +Array.make(~length=6, 7)->assertEqual([7, 7, 7, 7, 7, 7]) +``` */ let make: (~length: int, 'a) => array<'a> /** - `fromInitializer(~length, f)` +`fromInitializer(~length, f)` + +Creates an array of length `length` initialized with the value returned from `f ` for each index. + +## Examples - Creates an array of length `length` initialized with the value returned from `f ` for each index. +```rescript +Array.fromInitializer(~length=3, i => i + 3)->assertEqual([3, 4, 5]) - ```res example - Array.fromInitializer(~length=3, i => i + 3) == [3, 4, 5] - ``` +Array.fromInitializer(~length=7, i => i + 3)->assertEqual([3, 4, 5, 6, 7, 8, 9]) +``` */ let fromInitializer: (~length: int, int => 'a) => array<'a> @@ -53,10 +63,13 @@ let compare: (array<'a>, array<'a>, ('a, 'a) => Ordering.t) => Ordering.t See [`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] -Console.log(someArray->Array.length) // 2 +someArray +->Array.length +->assertEqual(2) ``` */ @get @@ -81,11 +94,11 @@ Beware this will *mutate* the array. See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. ## Examples + ```rescript let myArray = [1, 2, 3, 4] myArray->Array.fillAll(9) - -Console.log(myArray) // [9, 9, 9, 9] +myArray->assertEqual([9, 9, 9, 9]) ``` */ @send @@ -99,11 +112,11 @@ Beware this will *mutate* the array. See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. ## Examples + ```rescript let myArray = [1, 2, 3, 4] myArray->Array.fillToEnd(9, ~start=1) - -Console.log(myArray) // [1, 9, 9, 9] +myArray->assertEqual([1, 9, 9, 9]) ``` */ @send @@ -117,11 +130,13 @@ Beware this will *mutate* the array. See [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN. ## Examples + ```rescript let myArray = [1, 2, 3, 4] -myArray->Array.fill(9, ~start=1, ~end=2) -Console.log(myArray) // [1, 9, 9, 4] +myArray->Array.fill(9, ~start=1, ~end=3) + +myArray->assertEqual([1, 9, 9, 4]) ``` */ @send @@ -135,11 +150,15 @@ Beware this will *mutate* the array. See [`Array.pop`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] -let lastItem = someArray->Array.pop // "hello" -Console.log(someArray) // ["hi"]. Notice last item is gone. +someArray +->Array.pop +->assertEqual(Some("hello")) + +someArray->assertEqual(["hi"]) // Notice last item is gone. ``` */ @send @@ -153,11 +172,13 @@ Beware this will *mutate* the array. See [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] + someArray->Array.push("yay") -Console.log(someArray) // ["hi", "hello", "yay"] +someArray->assertEqual(["hi", "hello", "yay"]) ``` */ @send @@ -171,11 +192,12 @@ Beware this will *mutate* the array. See [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] -someArray->Array.pushMany(["yay", "wehoo"]) -Console.log(someArray) // ["hi", "hello", "yay", "wehoo"] +someArray->Array.pushMany(["yay", "wehoo"]) +someArray->assertEqual(["hi", "hello", "yay", "wehoo"]) ``` */ @variadic @@ -190,11 +212,12 @@ Beware this will *mutate* the array. See [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] someArray->Array.reverse -Console.log(someArray) // ["hello", "h1"] +someArray->assertEqual(["hello", "hi"]) ``` */ @send @@ -208,11 +231,15 @@ Beware this will *mutate* the array. See [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] -let lastItem = someArray->Array.shift // "hi" -Console.log(someArray) // ["hello"]. Notice first item is gone. +someArray +->Array.shift +->assertEqual(Some("hi")) + +someArray->assertEqual(["hello"]) // Notice first item is gone. ``` */ @send @@ -224,12 +251,15 @@ external shift: array<'a> => option<'a> = "shift" See [`Array.toSorted`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted) on MDN. ## Examples + ```rescript let someArray = [3, 2, 1] -let sorted = someArray->Array.toSorted(Int.compare) -Console.log(sorted) // [1, 2, 3] -Console.log(someArray) // [3, 2, 1]. Original unchanged +someArray +->Array.toSorted(Int.compare) +->assertEqual([1, 2, 3]) + +someArray->assertEqual([3, 2, 1]) // Original unchanged ``` */ @send @@ -243,11 +273,11 @@ Beware this will *mutate* the array. See [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN. ## Examples -```rescript -let someArray = [3, 2, 1] -someArray->Array.sort((a, b) => float(a - b)) -Console.log(someArray) // [1, 2, 3] +```rescript +let array = [3, 2, 1] +array->Array.sort((a, b) => float(a - b)) +array->assertEqual([1, 2, 3]) ``` */ @send @@ -270,11 +300,11 @@ Beware this will *mutate* the array. See [`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] someArray->Array.unshift("yay") - -Console.log(someArray) // ["yay", "hi", "hello"] +someArray->assertEqual(["yay", "hi", "hello"]) ``` */ @send @@ -288,11 +318,11 @@ Beware this will *mutate* the array. See [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] someArray->Array.unshiftMany(["yay", "wehoo"]) - -Console.log(someArray) // ["yay", "wehoo", "hi", "hello"] +someArray->assertEqual(["yay", "wehoo", "hi", "hello"]) ``` */ @variadic @@ -305,13 +335,14 @@ external unshiftMany: (array<'a>, array<'a>) => unit = "unshift" See [`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) on MDN. ## Examples + ```rescript let array1 = ["hi", "hello"] let array2 = ["yay", "wehoo"] let someArray = array1->Array.concat(array2) -Console.log(someArray) // ["hi", "hello", "yay", "wehoo"] +someArray->assertEqual(["hi", "hello", "yay", "wehoo"]) ``` */ @send @@ -343,8 +374,11 @@ external concatMany: (array<'a>, array>) => array<'a> = "concat" See [`Array.flat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) on MDN. ## Examples + ```rescript -Console.log([[1], [2], [3, 4]]->Array.flat) // [1, 2, 3, 4] +[[1], [2], [3, 4]] +->Array.flat +->assertEqual([1, 2, 3, 4]) ``` */ @send @@ -356,10 +390,14 @@ external flat: array> => array<'a> = "flat" See [`Array.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) on MDN. ## Examples + ```rescript -Console.log([1, 2]->Array.includes(1)) // true -Console.log([1, 2]->Array.includes(3)) // false -Console.log([{"language": "ReScript"}]->Array.includes({"language": "ReScript"})) // false, because of strict equality +[1, 2]->Array.includes(1)->assertEqual(true) +[1, 2]->Array.includes(3)->assertEqual(false) + +[{"language": "ReScript"}] +->Array.includes({"language": "ReScript"}) +->assertEqual(false) // false, because of strict equality ``` */ @send @@ -373,10 +411,14 @@ Returns `-1` if the item doesn not exist. Check out `Array.indexOfOpt` for a ver See [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) on MDN. ## Examples + ```rescript -Console.log([1, 2]->Array.indexOf(2)) // 1 -Console.log([1, 2]->Array.indexOf(3)) // -1 -Console.log([{"language": "ReScript"}]->Array.indexOf({"language": "ReScript"})) // -1, because of strict equality +[1, 2]->Array.indexOf(2)->assertEqual(1) +[1, 2]->Array.indexOf(3)->assertEqual(-1) + +[{"language": "ReScript"}] +->Array.indexOf({"language": "ReScript"}) +->assertEqual(-1) // -1, because of strict equality ``` */ @send @@ -388,10 +430,13 @@ external indexOf: (array<'a>, 'a) => int = "indexOf" See [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) on MDN. ## Examples + ```rescript -Console.log([1, 2]->Array.indexOfOpt(2)) // Some(1) -Console.log([1, 2]->Array.indexOfOpt(3)) // None -Console.log([{"language": "ReScript"}]->Array.indexOfOpt({"language": "ReScript"})) // None, because of strict equality +[1, 2]->Array.indexOfOpt(2)->assertEqual(Some(1)) +[1, 2]->Array.indexOfOpt(3)->assertEqual(None) +[{"language": "ReScript"}] +->Array.indexOfOpt({"language": "ReScript"}) +->assertEqual(None) // None, because of strict equality ``` */ let indexOfOpt: (array<'a>, 'a) => option @@ -403,10 +448,11 @@ let indexOfOpt: (array<'a>, 'a) => option See [Array.join](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) ## Examples -```rescript -let array = ["One", "Two", "Three"] -Console.log(array->Array.join(" -- ")) // One -- Two -- Three +```rescript +["One", "Two", "Three"] +->Array.join(" -- ") +->assertEqual("One -- Two -- Three") ``` */ @send @@ -416,10 +462,11 @@ external join: (array, string) => string = "join" `joinWith(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Array items must be strings, to join number or other arrays, use `joinWithUnsafe`. Under the hood this will run JavaScript's `toString` on all the array items. ## Examples -```rescript -let array = ["One", "Two", "Three"] -Console.log(array->Array.joinWith(" -- ")) // One -- Two -- Three +```rescript +["One", "Two", "Three"] +->Array.joinWith(" -- ") +->assertEqual("One -- Two -- Three") ``` */ @deprecated("Use `join` instead") @@ -432,10 +479,11 @@ external joinWith: (array, string) => string = "join" See [Array.join](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join) ## Examples -```rescript -let array = [1, 2, 3] -Console.log(array->Array.joinUnsafe(" -- ")) // 1 -- 2 -- 3 +```rescript +[1, 2, 3] +->Array.joinUnsafe(" -- ") +->assertEqual("1 -- 2 -- 3") ``` */ @send @@ -445,10 +493,11 @@ external joinUnsafe: (array<'a>, string) => string = "join" `joinWithUnsafe(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Under the hood this will run JavaScript's `toString` on all the array items. ## Examples -```rescript -let array = [1, 2, 3] -Console.log(array->Array.joinWithUnsafe(" -- ")) // 1 -- 2 -- 3 +```rescript +[1, 2, 3] +->Array.joinWithUnsafe(" -- ") +->assertEqual("1 -- 2 -- 3") ``` */ @deprecated("Use `joinUnsafe` instead") @@ -464,10 +513,11 @@ let lastIndexOfOpt: (array<'a>, 'a) => option See [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN. ## Examples -```rescript -let myArray = [1, 2, 3, 4] -Console.log(myArray->Array.slice(~start=1, ~end=3)) // [2, 3] +```rescript +[1, 2, 3, 4] +->Array.slice(~start=1, ~end=3) +->assertEqual([2, 3]) ``` */ @send @@ -479,10 +529,11 @@ external slice: (array<'a>, ~start: int, ~end: int) => array<'a> = "slice" See [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN. ## Examples -```rescript -let myArray = [1, 2, 3, 4] -Console.log(myArray->Array.sliceToEnd(~start=1)) // [2, 3, 4] +```rescript +[1, 2, 3, 4] +->Array.sliceToEnd(~start=1) +->assertEqual([2, 3, 4]) ``` */ @send @@ -491,12 +542,13 @@ external sliceToEnd: (array<'a>, ~start: int) => array<'a> = "slice" `copy(array)` makes a copy of the array with the items in it, but does not make copies of the items themselves. ## Examples + ```rescript let myArray = [1, 2, 3] let copyOfMyArray = myArray->Array.copy -Console.log(copyOfMyArray) // [1, 2, 3] -Console.log(myArray === copyOfMyArray) // false +copyOfMyArray->assertEqual([1, 2, 3]) +assertEqual(myArray === copyOfMyArray, false) ``` */ @send @@ -508,10 +560,11 @@ external copy: array<'a> => array<'a> = "slice" See [`Array.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) on MDN. ## Examples -```rescript -let array = [1, 2, 3, 4] -Console.log(array->Array.toString) // "1,2,3,4" +```rescript +[1, 2, 3, 4] +->Array.toString +->assertEqual("1,2,3,4") ``` */ @send @@ -525,11 +578,17 @@ external toString: array<'a> => string = "toString" See [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN. ## Examples + ```rescript let array = [1, 2, 3, 4] -Console.log(array->Array.every(num => num <= 4)) // true -Console.log(array->Array.every(num => num === 1)) // false +array +->Array.every(num => num <= 4) +->assertEqual(true) + +array +->Array.every(num => num === 1) +->assertEqual(false) ``` */ @send @@ -541,11 +600,17 @@ external every: (array<'a>, 'a => bool) => bool = "every" See [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN. ## Examples + ```rescript let array = [1, 2, 3, 4] -Console.log(array->Array.everyWithIndex((num, index) => index < 2 && num <= 2)) // true -Console.log(array->Array.everyWithIndex((num, index) => index < 2 && num >= 2)) // false +array +->Array.everyWithIndex((num, index) => index < 5 && num <= 4) +->assertEqual(true) + +array +->Array.everyWithIndex((num, index) => index < 2 && num >= 2) +->assertEqual(false) ``` */ @send @@ -557,10 +622,11 @@ external everyWithIndex: (array<'a>, ('a, int) => bool) => bool = "every" See [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN. ## Examples -```rescript -let array = [1, 2, 3, 4] -Console.log(array->Array.filter(num => num > 2)) // [3, 4] +```rescript +[1, 2, 3, 4] +->Array.filter(num => num > 2) +->assertEqual([3, 4]) ``` */ @send @@ -572,10 +638,11 @@ external filter: (array<'a>, 'a => bool) => array<'a> = "filter" See [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN. ## Examples -```rescript -let array = [1, 2, 3, 4] -Console.log(array->Array.filterWithIndex((num, index) => index === 0 || num === 2)) // [1, 2] +```rescript +[1, 2, 3, 4] +->Array.filterWithIndex((num, index) => index === 0 || num === 2) +->assertEqual([1, 2]) ``` */ @send @@ -587,15 +654,15 @@ external filterWithIndex: (array<'a>, ('a, int) => bool) => array<'a> = "filter" See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. ## Examples + ```rescript type languages = ReScript | TypeScript | JavaScript let array = [ReScript, TypeScript, JavaScript] -switch array->Array.find(item => item == ReScript) { -| None => Console.log("No item...") -| Some(_) => Console.log("Yay, ReScript!") -} +array +->Array.find(item => item == ReScript) +->assertEqual(Some(ReScript)) ``` */ @send @@ -607,15 +674,15 @@ external find: (array<'a>, 'a => bool) => option<'a> = "find" See [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN. ## Examples + ```rescript type languages = ReScript | TypeScript | JavaScript let array = [TypeScript, JavaScript, ReScript] -switch array->Array.findWithIndex((item, index) => index > 1 && item == ReScript) { -| None => Console.log("No item...") -| Some(_) => Console.log("Yay, ReScript exists in a later position!") -} +array +->Array.findWithIndex((item, index) => index > 1 && item == ReScript) +->assertEqual(Some(ReScript)) ``` */ @send @@ -629,13 +696,18 @@ Returns `-1` if the item does not exist. Consider using `Array.findIndexOpt` if See [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN. ## Examples + ```rescript type languages = ReScript | TypeScript | JavaScript let array = [ReScript, JavaScript] -Console.log(array->Array.findIndex(item => item == ReScript)) // 0 -Console.log(array->Array.findIndex(item => item == TypeScript)) // -1 +array +->Array.findIndex(item => item == ReScript) +->assertEqual(0) + +array->Array.findIndex(item => item == TypeScript) +->assertEqual(-1) ``` */ @send @@ -649,6 +721,7 @@ Returns `-1` if the item does not exist. Consider using `Array.findIndexOpt` if See [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN. ## Examples + ```rescript type languages = ReScript | TypeScript | JavaScript @@ -657,8 +730,8 @@ let array = [ReScript, JavaScript] let isReScriptFirst = array->Array.findIndexWithIndex((item, index) => index === 0 && item == ReScript) let isTypeScriptFirst = array->Array.findIndexWithIndex((item, index) => index === 0 && item == TypeScript) -Console.log(isReScriptFirst) // 0 -Console.log(isTypeScriptFirst) // -1 +assertEqual(isReScriptFirst, 0) +assertEqual(isTypeScriptFirst, -1) ``` */ @send @@ -687,6 +760,7 @@ external forEach: (array<'a>, 'a => unit) => unit = "forEach" See [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) on MDN. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] @@ -704,11 +778,12 @@ external forEachWithIndex: (array<'a>, ('a, int) => unit) => unit = "forEach" See [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] let mappedArray = array->Array.map(greeting => greeting ++ " to you") -Console.log(mappedArray) // ["Hello to you", "Hi to you", "Good bye to you"] +assertEqual(mappedArray, ["Hello to you", "Hi to you", "Good bye to you"]) ``` */ @send @@ -720,6 +795,7 @@ external map: (array<'a>, 'a => 'b) => array<'b> = "map" See [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] let mappedArray = @@ -727,55 +803,79 @@ let mappedArray = greeting ++ " at position " ++ Int.toString(index) ) -Console.log(mappedArray) // ["Hello at position 0", "Hi at position 1", "Good bye at position 2"] +assertEqual(mappedArray, ["Hello at position 0", "Hi at position 1", "Good bye at position 2"]) ``` */ @send external mapWithIndex: (array<'a>, ('a, int) => 'b) => array<'b> = "map" /** - `reduce(xs, init, fn)` +`reduce(xs, init, fn)` - Applies `fn` to each element of `xs` from beginning to end. Function `fn` has two parameters: the item from the list and an “accumulator”; which starts with a value of `init`. `reduce` returns the final value of the accumulator. +Applies `fn` to each element of `xs` from beginning to end. Function `fn` has two parameters: the item from the list and an “accumulator”; which starts with a value of `init`. `reduce` returns the final value of the accumulator. - ```res example - Array.reduce([2, 3, 4], 1, (a, b) => a + b) == 10 +## Examples + +```rescript +Array.reduce([2, 3, 4], 1, (a, b) => a + b)->assertEqual(10) + +Array.reduce(["a", "b", "c", "d"], "", (a, b) => a ++ b)->assertEqual("abcd") + +[1, 2, 3] +->Array.reduce(list{}, List.add) +->assertEqual(list{3, 2, 1}) - Array.reduce(["a", "b", "c", "d"], "", (a, b) => a ++ b) == "abcd" - ``` +Array.reduce([], list{}, List.add)->assertEqual(list{}) +``` */ let reduce: (array<'a>, 'b, ('b, 'a) => 'b) => 'b /** - `reduceWithIndex(x, init, fn)` +`reduceWithIndex(x, init, fn)` + +Applies `fn` to each element of `xs` from beginning to end. Function `fn` has three parameters: the item from the array and an “accumulator”, which starts with a value of `init` and the index of each element. `reduceWithIndex` returns the final value of the accumulator. - Applies `fn` to each element of `xs` from beginning to end. Function `fn` has three parameters: the item from the array and an “accumulator”, which starts with a value of `init` and the index of each element. `reduceWithIndex` returns the final value of the accumulator. +## Examples + +```rescript +Array.reduceWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i)->assertEqual(16) - ```res example - Array.reduceWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i) == 16 - ``` +Array.reduceWithIndex([1, 2, 3], list{}, (acc, v, i) => list{v + i, ...acc})->assertEqual(list{5, 3, 1}) + +Array.reduceWithIndex([], list{}, (acc, v, i) => list{v + i, ...acc})->assertEqual(list{}) +``` */ let reduceWithIndex: (array<'a>, 'b, ('b, 'a, int) => 'b) => 'b /** - `reduceRight(xs, init, fn)` +`reduceRight(xs, init, fn)` + +Works like `Array.reduce`; except that function `fn` is applied to each item of `xs` from the last back to the first. + +## Examples - Works like `Array.reduce`; except that function `fn` is applied to each item of `xs` from the last back to the first. +```rescript +Array.reduceRight(["a", "b", "c", "d"], "", (a, b) => a ++ b)->assertEqual("dcba") + +Array.reduceRight([1, 2, 3], list{}, List.add)->assertEqual(list{1, 2, 3}) - ```res example - Array.reduceRight(["a", "b", "c", "d"], "", (a, b) => a ++ b) == "dcba" - ``` +Array.reduceRight([], list{}, List.add)->assertEqual(list{}) +``` */ let reduceRight: (array<'a>, 'b, ('b, 'a) => 'b) => 'b /** - `reduceRightWithIndex(xs, init, fn)` +`reduceRightWithIndex(xs, init, fn)` - Like `reduceRight`, but with an additional index argument on the callback function. +Like `reduceRight`, but with an additional index argument on the callback function. + +## Examples - ```res example - Array.reduceRightWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i) == 16 - ``` +```rescript +Array.reduceRightWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i)->assertEqual(16) + +Array.reduceRightWithIndex([], list{}, (acc, v, i) => list{v + i, ...acc})->assertEqual(list{}) +``` */ let reduceRightWithIndex: (array<'a>, 'b, ('b, 'a, int) => 'b) => 'b @@ -785,10 +885,13 @@ let reduceRightWithIndex: (array<'a>, 'b, ('b, 'a, int) => 'b) => 'b See [`Array.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) on MDN. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] -Console.log(array->Array.some(greeting => greeting === "Hello")) // true +array +->Array.some(greeting => greeting === "Hello") +->assertEqual(true) ``` */ @send @@ -800,10 +903,13 @@ external some: (array<'a>, 'a => bool) => bool = "some" See [`Array.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) on MDN. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] -Console.log(array->Array.someWithIndex((greeting, index) => greeting === "Hello" && index === 0)) // true +array +->Array.someWithIndex((greeting, index) => greeting === "Hello" && index === 0) +->assertEqual(true) ``` */ @send @@ -815,11 +921,17 @@ external someWithIndex: (array<'a>, ('a, int) => bool) => bool = "some" Returns `None` if the index does not exist in the array. Equivalent to doing `array[index]` in JavaScript. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] -array->Array.get(0) == Some("Hello") // true -array->Array.get(3) == None // true +array +->Array.get(0) +->assertEqual(Some("Hello")) + +array +->Array.get(3) +->assertEqual(None) ``` */ @get_index @@ -831,11 +943,12 @@ external get: (array<'a>, int) => option<'a> = "" Beware this will *mutate* the array. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] array->Array.set(1, "Hello") -Console.log(array[1]) // "Hello" +array[1]->assertEqual(Some("Hello")) ``` */ @set_index @@ -870,6 +983,7 @@ This is _unsafe_, meaning it will return `undefined` value if `index` does not e Use `Array.unsafe_get` only when you are sure the `index` exists (i.e. when using for-loop). ## Examples + ```rescript let array = [1, 2, 3] for index in 0 to array->Array.length - 1 { @@ -887,11 +1001,12 @@ external unsafe_get: (array<'a>, int) => 'a = "%array_unsafe_get" Beware this will *mutate* the array, and is *unsafe*. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] array->Array.setUnsafe(1, "Hello") -Console.log(array[1]) // "Hello" +assertEqual(array[1], Some("Hello")) ``` */ external setUnsafe: (array<'a>, int, 'a) => unit = "%array_unsafe_set" @@ -904,15 +1019,15 @@ Returns `None` if no item matches. See [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN. ## Examples + ```rescript type languages = ReScript | TypeScript | JavaScript let array = [ReScript, TypeScript, JavaScript] -switch array->Array.findIndexOpt(item => item == ReScript) { -| None => Console.log("Ahh, no ReScript...") -| Some(index) => Console.log("Yay, ReScript at index " ++ Int.toString(index)) -} +array +->Array.findIndexOpt(item => item == ReScript) +->assertEqual(Some(0)) ``` */ let findIndexOpt: (array<'a>, 'a => bool) => option @@ -923,12 +1038,13 @@ let findIndexOpt: (array<'a>, 'a => bool) => option See [`Array.toReversed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed) on MDN. ## Examples + ```rescript let someArray = ["hi", "hello"] let reversed = someArray->Array.toReversed -Console.log(reversed) // ["hello", "h1"] -Console.log(someArray) // ["h1", "hello"]. Original unchanged +reversed->assertEqual(["hello", "hi"]) +someArray->assertEqual(["h1", "hello"]) // Original unchanged ``` */ @send @@ -940,30 +1056,45 @@ external toReversed: array<'a> => array<'a> = "toReversed" Calls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`. ## Examples + ```rescript -let array = ["Hello", "Hi", "Good bye"] +["Hello", "Hi", "Good bye"] +->Array.filterMap(item => + switch item { + | "Hello" => Some(item->String.length) + | _ => None + } +) +->assertEqual([5]) + +[1, 2, 3, 4, 5, 6] +->Array.filterMap(n => mod(n, 2) == 0 ? Some(n * n) : None) +->assertEqual([4, 16, 36]) -Console.log( - array->Array.filterMap(item => - switch item { - | "Hello" => Some(item->String.length) - | _ => None - } - ), -) // [5] +Array.filterMap([1, 2, 3, 4, 5, 6], _ => None)->assertEqual([]) + +Array.filterMap([], n => mod(n, 2) == 0 ? Some(n * n) : None)->assertEqual([]) ``` */ let filterMap: (array<'a>, 'a => option<'b>) => array<'b> /** - `keepSome(arr)` +`keepSome(arr)` + +Returns a new array containing `value` for all elements that are `Some(value)` +and ignoring every value that is `None` - Returns a new array containing `value` for all elements that are `Some(value)` - and ignoring every value that is `None` +## Examples + +```rescript +Array.keepSome([Some(1), None, Some(3)])->assertEqual([1, 3]) + +Array.keepSome([Some(1), Some(2), Some(3)])->assertEqual([1, 2, 3]) + +Array.keepSome([None, None, None])->assertEqual([]) - ```res example - Array.keepSome([Some(1), None, Some(3)]) == [1, 3] - ``` +Array.keepSome([])->assertEqual([]) +``` */ let keepSome: array> => array<'a> @@ -971,11 +1102,15 @@ let keepSome: array> => array<'a> `toShuffled(array)` returns a new array with all items in `array` in a random order. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] let shuffledArray = array->Array.toShuffled - Console.log(shuffledArray) + +Array.toShuffled([1, 2, 3]) +->Array.length +->assertEqual(3) ``` */ let toShuffled: array<'a> => array<'a> @@ -986,11 +1121,18 @@ let toShuffled: array<'a> => array<'a> Beware this will *mutate* the array. ## Examples + ```rescript let array = ["Hello", "Hi", "Good bye"] array->Array.shuffle - Console.log(array) + +let array2 = [1, 2, 3] +array2->Array.shuffle + +array2 +->Array.length +->assertEqual(3) ``` */ let shuffle: array<'a> => unit @@ -999,21 +1141,21 @@ let shuffle: array<'a> => unit `flatMap(array, mapper)` returns a new array concatenating the arrays returned from running `mapper` on all items in `array`. ## Examples + ```rescript type language = ReScript | TypeScript | JavaScript let array = [ReScript, TypeScript, JavaScript] -Console.log( - array->Array.flatMap(item => - switch item { - | ReScript => [1, 2, 3] - | TypeScript => [4, 5, 6] - | JavaScript => [7, 8, 9] - } - ), +array +->Array.flatMap(item => + switch item { + | ReScript => [1, 2, 3] + | TypeScript => [4, 5, 6] + | JavaScript => [7, 8, 9] + } ) -// [1, 2, 3, 4, 5, 6, 7, 8, 9] +->assertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]) ``` */ @send @@ -1023,52 +1165,62 @@ external flatMap: (array<'a>, 'a => array<'b>) => array<'b> = "flatMap" `flatMapWithIndex(array, mapper)` returns a new array concatenating the arrays returned from running `mapper` on all items in `array`. ## Examples + ```rescript type language = ReScript | TypeScript | JavaScript let array = [ReScript, TypeScript, JavaScript] -Console.log( - array->Array.flatMapWithIndex((item, index) => - switch item { - | ReScript => [index] - | TypeScript => [index, index + 1] - | JavaScript => [index, index + 1, index + 2] - } - ), + +array +->Array.flatMapWithIndex((item, index) => + switch item { + | ReScript => [index] + | TypeScript => [index, index + 1] + | JavaScript => [index, index + 1, index + 2] + } ) -// [0, 1, 2, 2, 3, 4] +->assertEqual([0, 1, 2, 2, 3, 4]) ``` */ @send external flatMapWithIndex: (array<'a>, ('a, int) => array<'b>) => array<'b> = "flatMap" /** - `findMap(arr, fn)` +`findMap(arr, fn)` + +Calls `fn` for each element and returns the first value from `fn` that is `Some(_)`. +Otherwise returns `None` - Calls `fn` for each element and returns the first value from `fn` that is `Some(_)`. - Otherwise returns `None` +## Examples + +```rescript +Array.findMap([1, 2, 3], n => mod(n, 2) == 0 ? Some(n - 2) : None)->assertEqual(Some(0)) - ```res example - Array.findMap([1, 2, 3], n => mod(n, 2) == 0 ? Some(n - 2) : None) == Some(0) // true - ``` +Array.findMap([1, 2, 3, 4, 5, 6], n => mod(n, 2) == 0 ? Some(n - 8) : None)->assertEqual(Some(-6)) + +Array.findMap([1, 2, 3, 4, 5, 6], _ => None)->assertEqual(None) + +Array.findMap([], n => mod(n, 2) == 0 ? Some(n * n) : None)->assertEqual(None) +``` */ let findMap: (array<'a>, 'a => option<'b>) => option<'b> /** - `at(array, index)` +`at(array, index)` - Get an element by its index. Negative indices count backwards from the last item. +Get an element by its index. Negative indices count backwards from the last item. + +## Examples - ## Examples - ```rescript - ["a", "b", "c"]->Array.at(0) // Some("a") - ["a", "b", "c"]->Array.at(2) // Some("c") - ["a", "b", "c"]->Array.at(3) // None - ["a", "b", "c"]->Array.at(-1) // Some("c") - ["a", "b", "c"]->Array.at(-3) // Some("a") - ["a", "b", "c"]->Array.at(-4) // None - ``` +```rescript +["a", "b", "c"]->Array.at(0)->assertEqual(Some("a")) +["a", "b", "c"]->Array.at(2)->assertEqual(Some("c")) +["a", "b", "c"]->Array.at(3)->assertEqual(None) +["a", "b", "c"]->Array.at(-1)->assertEqual(Some("c")) +["a", "b", "c"]->Array.at(-3)->assertEqual(Some("a")) +["a", "b", "c"]->Array.at(-4)->assertEqual(None) +``` */ @send external at: (array<'a>, int) => option<'a> = "at" @@ -1079,11 +1231,15 @@ external at: (array<'a>, int) => option<'a> = "at" Returns `None` if the array is empty. ## Examples + ```rescript -let array = ["Hello", "Hi", "Good bye"] +["Hello", "Hi", "Good bye"] +->Array.last +->assertEqual(Some("Good bye")) -array->Array.last == Some("Good bye") // true -[]->Array.last == None // true +[] +->Array.last +->assertEqual(None) ``` */ let last: array<'a> => option<'a> diff --git a/runtime/AsyncIterator.resi b/runtime/AsyncIterator.resi index bbe8de3b09..57277875ed 100644 --- a/runtime/AsyncIterator.resi +++ b/runtime/AsyncIterator.resi @@ -20,59 +20,64 @@ type value<'a> = { } /** - `make(nextFn)` +`make(nextFn)` - Creates an async iterator from a function that returns the next value of the iterator. +Creates an async iterator from a function that returns the next value of the iterator. - ## Examples - - A simple example, creating an async iterator that returns 1, 2, 3: - ```rescript - let context = ref(0) +## Examples - let asyncIterator = AsyncIterator.make(async () => { - let currentValue = context.contents - // Increment current value - context := currentValue + 1 - - { - AsyncIterator.value: Some(currentValue), - done: currentValue >= 3 - } - }) +- A simple example, creating an async iterator that returns 1, 2, 3: - // This will log 1, 2, 3 - await asyncIterator->AsyncIterator.forEach(value => - switch value { - | Some(value) => Console.log(value) - | None => () - } - ) - ``` - */ +```rescript +let context = ref(0) + +let asyncIterator = AsyncIterator.make(async () => { + let currentValue = context.contents + // Increment current value + context := currentValue + 1 + + { + AsyncIterator.value: Some(currentValue), + done: currentValue >= 3 + } +}) + +// This will log 1, 2, 3 +let main = async () => await asyncIterator->AsyncIterator.forEach(value => + switch value { + | Some(value) => Console.log(value) + | None => () + } +) + +main()->ignore +``` +*/ let make: (unit => promise>) => t<'value> /** - `value(value)` +`value(value)` - Shorthand for creating a value object with the provided value, and the `done` property set to false. +Shorthand for creating a value object with the provided value, and the `done` property set to false. - ## Examples - ```rescript - let context = ref(0) +## Examples - let asyncIterator = AsyncIterator.make(async () => { - let currentValue = context.contents - // Increment current value - context := currentValue + 1 - - if currentValue >= 3 { - AsyncIterator.done() - } else { - AsyncIterator.value(currentValue) - } - }) - ``` - */ +```rescript +let context = ref(0) + +let asyncIterator = AsyncIterator.make(async () => { + let currentValue = context.contents + // Increment current value + context := currentValue + 1 + + if currentValue >= 3 { + AsyncIterator.done() + } else { + AsyncIterator.value(currentValue) + } +}) +``` +*/ let value: 'value => value<'value> /** @@ -107,17 +112,21 @@ Returns the next value of the iterator, if any. See [async iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols) on MDN. ## Examples + - A simple example, getting the next value: -```rescript -@val external asyncIterator: AsyncIterator.t = "someAsyncIterator" -let value = await asyncIterator->AsyncIterator.next -``` -- Complete example, including looping over all values: ```rescript -// Let's pretend we get an async iterator returning ints from somewhere. -@val external asyncIterator: AsyncIterator.t = "someAsyncIterator" +let asyncIterator: AsyncIterator.t<(string, string)> = %raw(` + (() => { + var map1 = new Map(); + + map1.set('first', '1'); + map1.set('second', '2'); + var iterator1 = map1[Symbol.iterator](); + return iterator1; + })() +`) let processMyAsyncIterator = async () => { // ReScript doesn't have `for ... of` loops, but it's easy to mimic using a while loop. @@ -130,10 +139,15 @@ let processMyAsyncIterator = async () => { // Exit the while loop if the iterator says it's done break := done - // This will log the (int) value of the current async iteration, if a value was returned. - Console.log(value) + if done { + value + ->Option.isNone + ->assertEqual(true) + } } } + +processMyAsyncIterator()->ignore ``` */ @send @@ -145,16 +159,30 @@ external next: t<'a> => promise> = "next" See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN. ## Examples + ```rescript // Let's pretend we get an async iterator returning ints from somewhere. -@val external asyncIterator: AsyncIterator.t = "someAsyncIterator" +let asyncIterator: AsyncIterator.t<(string, string)> = %raw(` + (() => { + var map1 = new Map(); + + map1.set('first', '1'); + map1.set('second', '2'); + + var iterator1 = map1[Symbol.iterator](); + return iterator1; + })() +`) + +let main = async () => + await asyncIterator->AsyncIterator.forEach(v => { + switch v { + | Some(("second", value)) => assertEqual(value, "2") + | _ => () + } + }) -await asyncIterator->AsyncIterator.forEach(value => - switch value { - | Some(value) if value > 10 => Console.log("More than 10!") - | _ => () - } -) +main()->ignore ``` */ let forEach: (t<'a>, option<'a> => unit) => promise diff --git a/runtime/Belt_Array.resi b/runtime/Belt_Array.resi index 4443dd1ff9..4674f4f80f 100644 --- a/runtime/Belt_Array.resi +++ b/runtime/Belt_Array.resi @@ -362,6 +362,7 @@ arr == [0, 1, 9, 9, 4] Belt.Array.fill(arr, ~offset=7, ~len=2, 8) arr == [0, 1, 9, 9, 4] +``` */ let fill: (t<'a>, ~offset: int, ~len: int, 'a) => unit diff --git a/runtime/Belt_Float.resi b/runtime/Belt_Float.resi index bc6fbf9915..87a6a9d6ef 100644 --- a/runtime/Belt_Float.resi +++ b/runtime/Belt_Float.resi @@ -77,7 +77,7 @@ Can be opened in a module to avoid dot-notation (`+.`), however this yields a sh ```rescript open Belt.Float -Js.log(2.0 + 2.0 === 4.0) /* true */ +assertEqual(2.0 + 2.0, 4.0) ``` */ external \"+": (float, float) => float = "%addfloat" @@ -90,7 +90,7 @@ Can be opened in a module to avoid dot-notation (`-.`), however this yields a sh ```rescript open Belt.Float -Js.log(2.0 - 1.0 === 1.0) /* true */ +assertEqual(2.0 - 1.0, 1.0) ``` */ external \"-": (float, float) => float = "%subfloat" @@ -103,7 +103,7 @@ Can be opened in a module to avoid dot-notation (`*.`), however this yields a sh ```rescript open Belt.Float -Js.log(2.0 * 2.0 === 4.0) /* true */ +assertEqual(2.0 * 2.0, 4.0) ``` */ external \"*": (float, float) => float = "%mulfloat" @@ -116,7 +116,7 @@ Can be opened in a module to avoid dot-notation (`/.`), however this yields a sh ```rescript open Belt.Float -Js.log(4.0 / 2.0 === 2.0) /* true */ +assertEqual(4.0 / 2.0, 2.0) ``` */ external \"/": (float, float) => float = "%divfloat" diff --git a/runtime/Belt_HashMap.resi b/runtime/Belt_HashMap.resi index 5a577dd188..0577b6a09e 100644 --- a/runtime/Belt_HashMap.resi +++ b/runtime/Belt_HashMap.resi @@ -33,11 +33,11 @@ _hash_ functions will have different type. ```rescript type t = int -module I0 = unpack(Belt.Id.hashable(~hash=(a: t) => "&"(a, 0xff_ff), ~eq=(a, b) => a == b)) -let s0: t<_, string, _> = make(~hintSize=40, ~id=module(I0)) +module I0 = unpack(Belt.Id.hashable(~hash=(_: t) => 0xff_ff, ~eq=(a, b) => a == b)) +let s0: Belt.HashMap.t = Belt.HashMap.make(~hintSize=40, ~id=module(I0)) -module I1 = unpack(Belt.Id.hashable(~hash=(a: t) => "&"(a, 0xff), ~eq=(a, b) => a == b)) -let s1: t<_, string, _> = make(~hintSize=40, ~id=module(I1)) +module I1 = unpack(Belt.Id.hashable(~hash=(_: t) => 0xff, ~eq=(a, b) => a == b)) +let s1: Belt.HashMap.t = Belt.HashMap.make(~hintSize=40, ~id=module(I1)) ``` The invariant must be held: for two elements who are _equal_, @@ -48,7 +48,7 @@ it would not mix. ## Examples -```rescript +``` let s0: t let s1: t ``` @@ -59,8 +59,8 @@ We can add elements to the collection: ```rescript let () = { - add(s1, 0, "3") - add(s1, 1, "3") + Belt.HashMap.set(s0, 0, 3) + Belt.HashMap.set(s1, 1, "3") } ``` @@ -282,10 +282,19 @@ module IntHash = Belt.Id.MakeHashable({ }) let s0 = Belt.HashMap.make(~hintSize=10, ~id=module(IntHash)) + Belt.HashMap.set(s0, 1, "value1") Belt.HashMap.set(s0, 2, "value2") -Belt.HashMap.reduce(s0, "", (acc, key, value) => acc ++ (", " ++ value)) == "value1, value2" +s0 +->Belt.HashMap.reduce("", (acc, _, value) => acc ++ (", " ++ value)) +->assertEqual(", value1, value2") +``` + +## More Examples + +```rescript +Console.log("lol") ``` */ let reduce: (t<'key, 'value, 'id>, 'c, ('c, 'key, 'value) => 'c) => 'c diff --git a/runtime/Belt_HashSet.resi b/runtime/Belt_HashSet.resi index b971f168d6..68309c8cbe 100644 --- a/runtime/Belt_HashSet.resi +++ b/runtime/Belt_HashSet.resi @@ -60,9 +60,9 @@ value should be the same. Here the compiler would infer `s0` and `s1` having different type so that it would not mix. -## Examples +Signatures: -```rescript +``` let s0: Belt.HashSet.t let s1: Belt.HashSet.t ``` diff --git a/runtime/Belt_Id.resi b/runtime/Belt_Id.resi index ca23d171b6..1da64ea212 100644 --- a/runtime/Belt_Id.resi +++ b/runtime/Belt_Id.resi @@ -93,17 +93,6 @@ module MakeComparable: ( @deprecated("Use `comparable` instead") let comparableU: (~cmp: ('a, 'a) => int) => module(Comparable with type t = 'a) -/** -## Examples - -```rescript -module C = ( - val Belt.Id.comparable ~cmp:(compare : int -> int -> int) -) -let m = Belt.Set.make(module C) -``` -Note that the name of C can not be ignored -*/ let comparable: (~cmp: ('a, 'a) => int) => module(Comparable with type t = 'a) module type Hashable = { diff --git a/runtime/Belt_Int.resi b/runtime/Belt_Int.resi index 0d64b76458..1ee951c34c 100644 --- a/runtime/Belt_Int.resi +++ b/runtime/Belt_Int.resi @@ -32,7 +32,7 @@ Converts a given `int` to a `float`. ## Examples ```rescript -Js.log(Belt.Int.toFloat(1) === 1.0) /* true */ +Belt.Int.toFloat(1)->assertEqual(1.0) ``` */ external toFloat: int => float = "%identity" @@ -43,7 +43,7 @@ Converts a given `float` to an `int`. ## Examples ```rescript -Js.log(Belt.Int.fromFloat(1.0) === 1) /* true */ +Belt.Int.fromFloat(1.0)->assertEqual(1) ``` */ external fromFloat: float => int = "%intoffloat" @@ -54,7 +54,7 @@ Converts a given `string` to an `int`. Returns `Some(int)` when the input is a n ## Examples ```rescript -Js.log(Belt.Int.fromString("1") === Some(1)) /* true */ +Belt.Int.fromString("1")->assertEqual(Some(1)) ``` */ let fromString: string => option @@ -65,7 +65,7 @@ Converts a given `int` to a `string`. Uses the JavaScript `String` constructor u ## Examples ```rescript -Js.log(Belt.Int.toString(1) === "1") /* true */ +Belt.Int.toString(1)->assertEqual("1") ``` */ @val @@ -78,7 +78,7 @@ Addition of two `int` values. Same as the addition from `Pervasives`. ```rescript open Belt.Int -Js.log(2 + 2 === 4) /* true */ +assertEqual(2 + 2, 4) ``` */ external \"+": (int, int) => int = "%addint" @@ -90,7 +90,7 @@ Subtraction of two `int` values. Same as the subtraction from `Pervasives`. ```rescript open Belt.Int -Js.log(2 - 1 === 1) /* true */ +assertEqual(2 - 1, 1) ``` */ external \"-": (int, int) => int = "%subint" @@ -102,7 +102,7 @@ Multiplication of two `int` values. Same as the multiplication from `Pervasives` ```rescript open Belt.Int -Js.log(2 * 2 === 4) /* true */ +assertEqual(2 * 2, 4) ``` */ external \"*": (int, int) => int = "%mulint" @@ -114,7 +114,7 @@ Division of two `int` values. Same as the division from `Pervasives`. ```rescript open Belt.Int -Js.log(4 / 2 === 2); /* true */ +assertEqual(4 / 2, 2) ``` */ external \"/": (int, int) => int = "%divint" diff --git a/runtime/Belt_List.resi b/runtime/Belt_List.resi index 6a29b27b8d..96d5fe1a46 100644 --- a/runtime/Belt_List.resi +++ b/runtime/Belt_List.resi @@ -69,9 +69,12 @@ with care. ## Examples ```rescript -Belt.List.headExn(list{1, 2, 3}) // 1 +Belt.List.headExn(list{1, 2, 3})->assertEqual(1) -Belt.List.headExn(list{}) // Raises an Error +switch Belt.List.headExn(list{}) { // Raises an Error +| exception _ => assert(true) +| _ => assert(false) +} ``` */ let headExn: t<'a> => 'a @@ -97,9 +100,12 @@ with care. ## Examples ```rescript -Belt.List.tailExn(list{1, 2, 3}) // list{2, 3} +Belt.List.tailExn(list{1, 2, 3})->assertEqual(list{2, 3}) -Belt.List.tailExn(list{}) // Raises an Error +switch Belt.List.tailExn(list{}) { // Raises an Error +| exception _ => assert(true) +| _ => assert(false) +} ``` */ let tailExn: t<'a> => t<'a> @@ -142,9 +148,12 @@ length. Use with care. ```rescript let abc = list{"A", "B", "C"} -abc->Belt.List.getExn(1) // "B" +abc->Belt.List.getExn(1)->assertEqual("B") -abc->Belt.List.getExn(4) // Raises an Error +switch abc->Belt.List.getExn(4) { // Raises an Error +| exception _ => assert(true) +| _ => assert(false) +} ``` */ let getExn: (t<'a>, int) => 'a @@ -377,16 +386,14 @@ let reverse: t<'a> => t<'a> let mapReverseU: (t<'a>, 'a => 'b) => t<'b> /** -Equivalent to: - -```res -map(someList, f)->reverse -``` +Equivalent to `Belt.List.map(someList, f)->Belt.List.reverse` ## Examples ```rescript -list{3, 4, 5}->Belt.List.mapReverse(x => x * x) /* list{25, 16, 9} */ +list{3, 4, 5} +->Belt.List.mapReverse(x => x * x) +->assertEqual(list{25, 16, 9}) ``` */ let mapReverse: (t<'a>, 'a => 'b) => t<'b> @@ -861,14 +868,16 @@ Creates a pair of lists; the first list consists of all elements of `someList` t In other words: -```rescript +``` (elementsThatSatisfies, elementsThatDoesNotSatisfy) ``` ## Examples ```rescript -Belt.List.partition(list{1, 2, 3, 4}, x => x > 2) /* (list{3, 4}, list{1, 2}) */ +list{1, 2, 3, 4} +->Belt.List.partition(x => x > 2) +->assertEqual((list{3, 4}, list{1, 2})) ``` */ let partition: (t<'a>, 'a => bool) => (t<'a>, t<'a>) diff --git a/runtime/Belt_Map.resi b/runtime/Belt_Map.resi index 59841d81f1..44cffe0685 100644 --- a/runtime/Belt_Map.resi +++ b/runtime/Belt_Map.resi @@ -131,7 +131,9 @@ module IntCmp = Belt.Id.MakeComparable({ let s0 = Belt.Map.fromArray(~id=module(IntCmp), [(4, "4"), (1, "1"), (2, "2"), (3, "")]) -Belt.Map.findFirstBy(s0, (k, v) => k == 4) /* (4, "4") */ +s0 +->Belt.Map.findFirstBy((k, _) => k == 4) +->assertEqual(Some(4, "4")) ``` */ let findFirstBy: (t<'k, 'v, 'id>, ('k, 'v) => bool) => option<('k, 'v)> diff --git a/runtime/Belt_MapInt.resi b/runtime/Belt_MapInt.resi index 34e1fb807c..0279527499 100644 --- a/runtime/Belt_MapInt.resi +++ b/runtime/Belt_MapInt.resi @@ -30,9 +30,14 @@ let findFirstByU: (t<'v>, (key, 'v) => bool) => option<(key, 'v)> `findFirstBy(m, p)` uses funcion `f` to find the first key value pair to match predicate `p`. +## Examples + ```rescript -let s0 = fromArray(~id=module(IntCmp), [(4, "4"), (1, "1"), (2, "2,"(3, ""))]) -findFirstBy(s0, (k, v) => k == 4) == option((4, "4")) +let mapInt = Belt.Map.Int.fromArray([(1, "one"), (2, "two"), (3, "three")]) + +mapInt-> +Belt.Map.Int.findFirstBy((k, v) => k == 1 && v == "one") +->assertEqual(Some(1, "one")) ``` */ let findFirstBy: (t<'v>, (key, 'v) => bool) => option<(key, 'v)> diff --git a/runtime/Belt_MapString.resi b/runtime/Belt_MapString.resi index 3a66652ca4..1a02bd2c1f 100644 --- a/runtime/Belt_MapString.resi +++ b/runtime/Belt_MapString.resi @@ -30,9 +30,14 @@ let findFirstByU: (t<'v>, (key, 'v) => bool) => option<(key, 'v)> `findFirstBy(m, p)` uses funcion `f` to find the first key value pair to match predicate `p`. +## Examples + ```rescript -let s0 = fromArray(~id=module(IntCmp), [(4, "4"), (1, "1"), (2, "2,"(3, ""))]) -findFirstBy(s0, (k, v) => k == 4) == option((4, "4")) +let mapString = Belt.Map.String.fromArray([("1", "one"), ("2", "two"), ("3", "three")]) + +mapString-> +Belt.Map.String.findFirstBy((k, v) => k == "1" && v == "one") +->assertEqual(Some("1", "one")) ``` */ let findFirstBy: (t<'v>, (key, 'v) => bool) => option<(key, 'v)> diff --git a/runtime/Belt_Option.resi b/runtime/Belt_Option.resi index 97f2a5934d..07013f0b00 100644 --- a/runtime/Belt_Option.resi +++ b/runtime/Belt_Option.resi @@ -79,9 +79,14 @@ Raises an Error in case `None` is provided. Use with care. ## Examples ```rescript -Belt.Option.getExn(Some(3)) /* 3 */ - -Belt.Option.getExn(None) /* Raises an Error */ +Some(3) +->Belt.Option.getExn +->assertEqual(3) + +switch Belt.Option.getExn(None) { // Raises an exception +| exception _ => assert(true) +| _ => assert(false) +} ``` */ let getExn: option<'a> => 'a diff --git a/runtime/Belt_Result.resi b/runtime/Belt_Result.resi index f3949d7577..da14ab6fd3 100644 --- a/runtime/Belt_Result.resi +++ b/runtime/Belt_Result.resi @@ -39,9 +39,15 @@ type t<'a, 'b> = result<'a, 'b> = ## Examples ```rescript -Belt.Result.getExn(Belt.Result.Ok(42)) == 42 +Belt.Result.Ok(42) +->Belt.Result.getExn +->assertEqual(42) -Belt.Result.getExn(Belt.Result.Error("Invalid data")) /* raises exception */ + +switch Belt.Result.getExn(Belt.Result.Error("Invalid data")) { // raise a exception +| exception _ => assert(true) +| _ => assert(false) +} ``` */ let getExn: t<'a, 'b> => 'a diff --git a/runtime/Belt_Set.resi b/runtime/Belt_Set.resi index 343c7dd0e3..b838a78991 100644 --- a/runtime/Belt_Set.resi +++ b/runtime/Belt_Set.resi @@ -97,7 +97,14 @@ Creates a new set by taking in the comparator ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let set = Belt.Set.make(~id=module(IntCmp)) + +Belt.Set.isEmpty(set)->assertEqual(true) ``` */ let make: (~id: id<'value, 'id>) => t<'value, 'id> @@ -108,9 +115,14 @@ Creates new set from array of elements. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([1, 3, 2, 4], ~id=module(IntCmp)) -s0->Belt.Set.toArray /* [1, 2, 3, 4] */ +s0->Belt.Set.toArray->assertEqual([1, 2, 3, 4]) ``` */ let fromArray: (array<'value>, ~id: id<'value, 'id>) => t<'value, 'id> @@ -127,11 +139,16 @@ Checks if set is empty. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let empty = Belt.Set.fromArray([], ~id=module(IntCmp)) -let notEmpty = Belt.Set.fromArray([1],~id=module(IntCmp)) +let notEmpty = Belt.Set.fromArray([1], ~id=module(IntCmp)) -Belt.Set.isEmpty(empty) /* true */ -Belt.Set.isEmpty(notEmpty) /* false */ +Belt.Set.isEmpty(empty)->assertEqual(true) +Belt.Set.isEmpty(notEmpty)->assertEqual(false) ``` */ let isEmpty: t<_> => bool @@ -142,10 +159,15 @@ Checks if element exists in set. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let set = Belt.Set.fromArray([1, 4, 2, 5], ~id=module(IntCmp)) -set->Belt.Set.has(3) /* false */ -set->Belt.Set.has(1) /* true */ +set->Belt.Set.has(3)->assertEqual(false) +set->Belt.Set.has(1)->assertEqual(true) ``` */ let has: (t<'value, 'id>, 'value) => bool @@ -156,15 +178,22 @@ Adds element to set. If element existed in set, value is unchanged. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.make(~id=module(IntCmp)) + let s1 = s0->Belt.Set.add(1) let s2 = s1->Belt.Set.add(2) let s3 = s2->Belt.Set.add(2) -s0->Belt.Set.toArray /* [] */ -s1->Belt.Set.toArray /* [1] */ -s2->Belt.Set.toArray /* [1, 2] */ -s3->Belt.Set.toArray /* [1,2 ] */ -s2 == s3 /* true */ + +s0->Belt.Set.toArray->assertEqual([]) +s1->Belt.Set.toArray->assertEqual([1]) +s2->Belt.Set.toArray->assertEqual([1, 2]) +s3->Belt.Set.toArray->assertEqual([1, 2]) +assertEqual(s2, s3) ``` */ let add: (t<'value, 'id>, 'value) => t<'value, 'id> @@ -175,10 +204,18 @@ Adds each element of array to set. Unlike `Belt.Set.add`](#add), the reference o ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let set = Belt.Set.make(~id=module(IntCmp)) let newSet = set->Belt.Set.mergeMany([5, 4, 3, 2, 1]) -newSet->Belt.Set.toArray /* [1, 2, 3, 4, 5] */ + +newSet +->Belt.Set.toArray +->assertEqual([1, 2, 3, 4, 5]) ``` */ let mergeMany: (t<'value, 'id>, array<'value>) => t<'value, 'id> @@ -189,14 +226,19 @@ Removes element from set. If element did not exist in set, value is unchanged. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([2,3,1,4,5], ~id=module(IntCmp)) let s1 = s0->Belt.Set.remove(1) let s2 = s1->Belt.Set.remove(3) let s3 = s2->Belt.Set.remove(3) -s1->Belt.Set.toArray /* [2,3,4,5] */ -s2->Belt.Set.toArray /* [2,4,5] */ -s2 == s3 /* true */ +s1->Belt.Set.toArray->assertEqual([2,3,4,5]) +s2->Belt.Set.toArray->assertEqual([2,4,5]) +assertEqual(s2, s3) ``` */ let remove: (t<'value, 'id>, 'value) => t<'value, 'id> @@ -207,10 +249,18 @@ Removes each element of array from set. Unlike [remove](#remove), the reference ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let set = Belt.Set.fromArray([1, 2, 3, 4],~id=module(IntCmp)) let newSet = set->Belt.Set.removeMany([5, 4, 3, 2, 1]) -newSet->Belt.Set.toArray /* [] */ + +newSet +->Belt.Set.toArray +->assertEqual([]) ``` */ let removeMany: (t<'value, 'id>, array<'value>) => t<'value, 'id> @@ -221,10 +271,18 @@ let removeMany: (t<'value, 'id>, array<'value>) => t<'value, 'id> ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) let union = Belt.Set.union(s0, s1) -union->Belt.Set.toArray /* [1,2,3,4,5,6] */ + +union +->Belt.Set.toArray +->assertEqual([1,2,3,4,5,6]) ``` */ let union: (t<'value, 'id>, t<'value, 'id>) => t<'value, 'id> @@ -235,10 +293,19 @@ Returns intersection of two sets. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) + let intersect = Belt.Set.intersect(s0, s1) -intersect->Belt.Set.toArray /* [2,3,5] */ + +intersect +->Belt.Set.toArray +->assertEqual([2,3,5]) ``` */ let intersect: (t<'value, 'id>, t<'value, 'id>) => t<'value, 'id> @@ -249,10 +316,21 @@ Returns elements from first set, not existing in second set. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) -Belt.Set.toArray(Belt.Set.diff(s0, s1)) /* [6] */ -Belt.Set.toArray(Belt.Set.diff(s1,s0)) /* [1,4] */ + +Belt.Set.diff(s0, s1) +->Belt.Set.toArray +->assertEqual([6]) + +Belt.Set.diff(s1,s0) +->Belt.Set.toArray +->assertEqual([1,4]) ``` */ let diff: (t<'value, 'id>, t<'value, 'id>) => t<'value, 'id> @@ -263,12 +341,18 @@ Checks if second set is subset of first set. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) let s1 = Belt.Set.fromArray([5,2,3,1,5,4], ~id=module(IntCmp)) let s2 = Belt.Set.intersect(s0, s1) -Belt.Set.subset(s2, s0) /* true */ -Belt.Set.subset(s2, s1) /* true */ -Belt.Set.subset(s1, s0) /* false */ + +Belt.Set.subset(s2, s0)->assertEqual(true) +Belt.Set.subset(s2, s1)->assertEqual(true) +Belt.Set.subset(s1, s0)->assertEqual(false) ``` */ let subset: (t<'value, 'id>, t<'value, 'id>) => bool @@ -286,10 +370,15 @@ Checks if two sets are equal. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([5,2,3], ~id=module(IntCmp)) let s1 = Belt.Set.fromArray([3,2,5], ~id=module(IntCmp)) -Belt.Set.eq(s0, s1) /* true */ +Belt.Set.eq(s0, s1)->assertEqual(true) ``` */ let eq: (t<'value, 'id>, t<'value, 'id>) => bool @@ -306,12 +395,20 @@ Applies function `f` in turn to all elements of set in increasing order. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) + let acc = ref(list{}) + s0->Belt.Set.forEach(x => { acc := Belt.List.add(acc.contents, x) }) -acc /* [6,5,3,2] */ + +acc.contents->assertEqual(list{6,5,3,2}) ``` */ let forEach: (t<'value, 'id>, 'value => unit) => unit @@ -325,10 +422,16 @@ Applies function `f` to each element of set in increasing order. Function `f` ha ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([5,2,3,5,6], ~id=module(IntCmp)) -s0->Belt.Set.reduce(list{}, (acc, element) => +s0 +->Belt.Set.reduce(list{}, (acc, element) => acc->Belt.List.add(element) -) /* [6,5,3,2] */ +)->assertEqual(list{6,5,3,2}) ``` */ let reduce: (t<'value, 'id>, 'a, ('a, 'value) => 'a) => 'a @@ -342,10 +445,15 @@ Checks if all elements of the set satisfy the predicate. Order unspecified. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let isEven = x => mod(x, 2) == 0 let s0 = Belt.Set.fromArray([2,4,6,8], ~id=module(IntCmp)) -s0->Belt.Set.every(isEven) /* true */ +s0->Belt.Set.every(isEven)->assertEqual(true) ``` */ let every: (t<'value, 'id>, 'value => bool) => bool @@ -359,10 +467,15 @@ Checks if at least one element of the set satisfies the predicate. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let isOdd = x => mod(x, 2) != 0 let s0 = Belt.Set.fromArray([1,2,4,6,8], ~id=module(IntCmp)) -s0->Belt.Set.some(isOdd) /* true */ +s0->Belt.Set.some(isOdd)->assertEqual(true) ``` */ let some: (t<'value, 'id>, 'value => bool) => bool @@ -376,12 +489,17 @@ Returns the set of all elements that satisfy the predicate. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let isEven = x => mod(x, 2) == 0 let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) let s1 = s0->Belt.Set.keep(isEven) -s1->Belt.Set.toArray /* [2,4] */ +s1->Belt.Set.toArray->assertEqual([2, 4]) ``` */ let keep: (t<'value, 'id>, 'value => bool) => t<'value, 'id> @@ -395,13 +513,18 @@ Returns a pair of sets, where first is the set of all the elements of set that s ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let isOdd = x => mod(x, 2) != 0 let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) let (s1, s2) = s0->Belt.Set.partition(isOdd) -s1->Belt.Set.toArray /* [1,3,5] */ -s2->Belt.Set.toArray /* [2,4] */ +s1->Belt.Set.toArray->assertEqual([1,3,5]) +s2->Belt.Set.toArray->assertEqual([2,4]) ``` */ let partition: (t<'value, 'id>, 'value => bool) => (t<'value, 'id>, t<'value, 'id>) @@ -412,9 +535,14 @@ Returns size of the set. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([1,2,3,4], ~id=module(IntCmp)) -s0->Belt.Set.size /* 4 */ +s0->Belt.Set.size->assertEqual(4) ``` */ let size: t<'value, 'id> => int @@ -425,9 +553,14 @@ Returns array of ordered set elements. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) -s0->Belt.Set.toArray /* [1,2,3,5] */ +s0->Belt.Set.toArray->assertEqual([1,2,3,5]) ``` */ let toArray: t<'value, 'id> => array<'value> @@ -438,9 +571,14 @@ Returns list of ordered set elements. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) -s0->Belt.Set.toList /* [1,2,3,5] */ +s0->Belt.Set.toList->assertEqual(list{1,2,3,5}) ``` */ let toList: t<'value, 'id> => list<'value> @@ -451,11 +589,16 @@ Returns minimum value of the collection. `None` if collection is empty. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.make(~id=module(IntCmp)) let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) -s0->Belt.Set.minimum /* None */ -s1->Belt.Set.minimum /* Some(1) */ +s0->Belt.Set.minimum->assertEqual(None) +s1->Belt.Set.minimum->assertEqual(Some(1)) ``` */ let minimum: t<'value, 'id> => option<'value> @@ -466,11 +609,16 @@ Returns minimum value of the collection. `undefined` if collection is empty. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.make(~id=module(IntCmp)) let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) -s0->Belt.Set.minUndefined /* undefined */ -s1->Belt.Set.minUndefined /* 1 */ +s0->Belt.Set.minUndefined->Js.Undefined.toOption->assertEqual(None) +s1->Belt.Set.minUndefined->Js.Undefined.toOption->assertEqual(Some(1)) ``` */ let minUndefined: t<'value, 'id> => Js.undefined<'value> @@ -481,11 +629,16 @@ Returns maximum value of the collection. `None` if collection is empty. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.make(~id=module(IntCmp)) let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) -s0->Belt.Set.maximum /* None */ -s1->Belt.Set.maximum /* Some(5) */ +s0->Belt.Set.maximum->assertEqual(None) +s1->Belt.Set.maximum->assertEqual(Some(5)) ``` */ let maximum: t<'value, 'id> => option<'value> @@ -496,11 +649,23 @@ Returns maximum value of the collection. `undefined` if collection is empty. ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.make(~id=module(IntCmp)) let s1 = Belt.Set.fromArray([3,2,1,5], ~id=module(IntCmp)) -s0->Belt.Set.maxUndefined /* undefined */ -s1->Belt.Set.maxUndefined /* 5 */ +s0 +->Belt.Set.maxUndefined +->Js.Undefined.toOption +->assertEqual(None) + +s1 +->Belt.Set.maxUndefined +->Js.Undefined.toOption +->assertEqual(Some(5)) ``` */ let maxUndefined: t<'value, 'id> => Js.undefined<'value> @@ -511,10 +676,15 @@ Returns the reference of the value which is equivalent to value using the compar ## Examples ```rescript +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) + let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) -s0->Belt.Set.get(3) /* Some(3) */ -s0->Belt.Set.get(20) /* None */ +s0->Belt.Set.get(3)->assertEqual(Some(3)) +s0->Belt.Set.get(20)->assertEqual(None) ``` */ let get: (t<'value, 'id>, 'value) => option<'value> @@ -535,14 +705,18 @@ Returns a tuple `((smaller, larger), present)`, `present` is true when element e ## Examples ```rescript -let s0 = Belt.Set.fromArray([1,2,3,4,5], ~id=module(IntCmp)) +module IntCmp = Belt.Id.MakeComparable({ + type t = int + let cmp = Pervasives.compare +}) -let ((smaller, larger), present) = s0->Belt.Set.split(3) +let s0 = Belt.Set.fromArray([1, 2, 3, 4, 5], ~id=module(IntCmp)) -present /* true */ -smaller->Belt.Set.toArray /* [1,2] */ -larger->Belt.Set.toArray /* [4,5] */ +let ((smaller, larger), present) = s0->Belt.Set.split(3) +present->assertEqual(true) +smaller->Belt.Set.toArray->assertEqual([1,2]) +larger->Belt.Set.toArray->assertEqual([4,5]) ``` */ let split: (t<'value, 'id>, 'value) => ((t<'value, 'id>, t<'value, 'id>), bool) diff --git a/runtime/Dict.resi b/runtime/Dict.resi index 77bb7e6d72..ffd5c2a377 100644 --- a/runtime/Dict.resi +++ b/runtime/Dict.resi @@ -95,11 +95,21 @@ external fromArray: array<(string, 'a)> => dict<'a> = "Object.fromEntries" `fromIterator(entries)` creates a new dictionary from the provided iterator of key/value pairs. ## Examples -```rescript -// Pretend we have an iterator of the correct shape -@val external someIterator: Iterator.t<(string, int)> = "someIterator" -let dict = Dict.fromIterator(someIterator) // dict +```rescript +let iterator: Iterator.t<(string, int)> = %raw(` + (() => { + var map1 = new Map(); + map1.set('first', 1); + map1.set('second', 2); + var iterator1 = map1[Symbol.iterator](); + return iterator1; + })() +`) +iterator +->Dict.fromIterator +->Dict.valuesToArray +->assertEqual([1, 2]) ``` */ @val diff --git a/runtime/Error.resi b/runtime/Error.resi index 21ce6da011..8636a9c4ee 100644 --- a/runtime/Error.resi +++ b/runtime/Error.resi @@ -165,8 +165,18 @@ handled. Compared to a ReScript exception this will give a better stack trace an debugging experience. ## Examples + ```rescript -Error.panic("Uh oh. This was unexpected!") +try { + Error.panic("Uh oh. This was unexpected!") +} catch { +| Exn.Error(obj) => + switch Exn.message(obj) { + | Some(m) => assert(m == "Panic! Uh oh. This was unexpected!") + | None => assert(false) + } +| _ => assert(false) +} ``` */ let panic: string => 'a diff --git a/runtime/Exn.resi b/runtime/Exn.resi index 31e8751e5f..e8dc04855b 100644 --- a/runtime/Exn.resi +++ b/runtime/Exn.resi @@ -48,18 +48,6 @@ that potentially is either exn, a JS error, or any other JS value really (e.g. f a value passed to a Promise.catch callback) **IMPORTANT**: This is an internal API and may be changed / removed any time in the future. - -## Examples - -```rescript -switch (Js.Exn.unsafeAnyToExn("test")) { -| Js.Exn.Error(v) => - switch(Js.Exn.message(v)) { - | Some(str) => Js.log("We won't end up here") - | None => Js.log2("We will land here: ", v) - } -} -``` */ external anyToExnInternal: 'a => exn = "%wrap_exn" diff --git a/runtime/Iterator.resi b/runtime/Iterator.resi index 300d4fca7b..b201710517 100644 --- a/runtime/Iterator.resi +++ b/runtime/Iterator.resi @@ -29,11 +29,17 @@ Returns the next value of the iterator, if any. See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) on MDN. ## Examples -```rescript -@val external someIterator: Iterator.t = "someIterator" -// Pulls out the next value of the iterator -let {Iterator.done, value} = someIterator->Iterator.next +```rescript +let iterator: Iterator.t = %raw(` + (() => { + var array1 = ['a']; + var iterator1 = array1[Symbol.iterator](); + return iterator1 + })() +`) +(iterator->Iterator.next).done->assertEqual(false) +(iterator->Iterator.next).done->assertEqual(true) ``` */ @send @@ -88,14 +94,22 @@ See [iterator protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript ## Examples ```rescript -@val external someIterator: Iterator.t = "someIterator" - -someIterator->Iterator.forEach(value => - switch value { - | Some(value) if value > 10 => Console.log("More than 10!") - | _ => () +let iterator: Iterator.t = %raw(` + (() => { + var array1 = ['a', 'b', 'c']; + var iterator1 = array1[Symbol.iterator](); + return iterator1 + })() +`) +iterator->Iterator.forEach(v => { + switch v { + | Some("a" | "b" | "c") => assert(true) + | other => + other + ->Option.isNone + ->assertEqual(true) } -) +}) ``` */ let forEach: (t<'a>, option<'a> => unit) => unit diff --git a/runtime/JSON.resi b/runtime/JSON.resi index 02f8b8793f..8d9e8b0494 100644 --- a/runtime/JSON.resi +++ b/runtime/JSON.resi @@ -297,7 +297,7 @@ JSON.stringifyWithFilterAndIndent(json, ["foo", "someNumber"], 2) external stringifyWithFilterAndIndent: (t, array, int) => string = "JSON.stringify" /** -`stringifyAny(any, ~replacer=?, ~space=?)` +`stringifyAny(any, ~replacer=?, ~space=?)` Converts any type to a JSON string. The replacer describes how the value should be transformed. It is a function which receives a key and a value. @@ -306,6 +306,7 @@ If the value contains circular references or `BigInt`s, the function will throw If you want to stringify a JSON object, use `JSON.stringify` instead. ## Examples + ```rescript let dict = Dict.fromArray([ ("foo", JSON.Encode.string("bar")), @@ -313,18 +314,24 @@ let dict = Dict.fromArray([ ("someNumber", JSON.Encode.int(42)), ]) -JSON.stringifyAny(dict) -// {"foo":"bar","hello":"world","someNumber":42} - -JSON.stringifyAny(dict, ~space=2) -// { -// "foo": "bar", -// "hello": "world", -// "someNumber": 42 -// } - -JSON.stringifyAny(dict, ~replacer=Keys(["foo", "someNumber"])) -// {"foo":"bar","someNumber":42} +dict +->JSON.stringifyAny +->Option.getUnsafe +->assertEqual(`{"foo":"bar","hello":"world","someNumber":42}`) + +dict +->JSON.stringifyAny(~space=2) +->Option.getUnsafe +->assertEqual(`{ + "foo": "bar", + "hello": "world", + "someNumber": 42 +}`) + +dict +->JSON.stringifyAny(~replacer=Keys(["foo", "someNumber"])) +->Option.getUnsafe +->assertEqual(`{"foo":"bar","someNumber":42}`) let replacer = JSON.Replacer((_, value) => { let decodedValue = value->JSON.Decode.string @@ -335,17 +342,22 @@ let replacer = JSON.Replacer((_, value) => { } }) -JSON.stringifyAny(dict, ~replacer) -// {"foo":"BAR","hello":"WORLD","someNumber":42} +dict +->JSON.stringifyAny(~replacer) +->Option.getUnsafe +->assertEqual(`{"foo":"BAR","hello":"WORLD","someNumber":42}`) JSON.stringifyAny(() => "hello world") -// None +->assertEqual(None) -BigInt.fromInt(0)->JSON.stringifyAny -// exception +// Raise a exception +switch BigInt.fromInt(0)->JSON.stringifyAny { +| exception _ => assert(true) +| _ => assert(false) +} ``` -## Exceptions +## Exceptions - Raises a TypeError if the value contains circular references. - Raises a TypeError if the value contains `BigInt`s. @@ -356,7 +368,7 @@ external stringifyAny: ('a, ~replacer: replacer=?, ~space: int=?) => optionJSON.stringifyAnyWithIndent(2) +->Option.getUnsafe +->assertEqual(`{ + "foo": "bar", + "hello": "world", + "someNumber": 42 +}`) -JSON.stringifyAny(() => "hello world") -// None +JSON.stringifyAny(() => "hello world")->assertEqual(None) -BigInt.fromInt(0)->JSON.stringifyAny -// exception +switch BigInt.fromInt(0)->JSON.stringifyAny { +| exception _ => assert(true) +| _ => assert(false) +} ``` ## Exceptions @@ -421,17 +437,20 @@ let replacer = (_, value) => { } } -JSON.stringifyAnyWithReplacer(dict, replacer) -// {"foo":"BAR","hello":"WORLD","someNumber":42} +dict +->JSON.stringifyAnyWithReplacer(replacer) +->Option.getUnsafe +->assertEqual(`{"foo":"BAR","hello":"WORLD","someNumber":42}`) -JSON.stringifyAny(() => "hello world") -// None +JSON.stringifyAny(() => "hello world")->assertEqual(None) -BigInt.fromInt(0)->JSON.stringifyAny -// exception +switch BigInt.fromInt(0)->JSON.stringifyAny { +| exception _ => assert(true) +| _ => assert(false) +} ``` -## Exceptions +## Exceptions - Raises a TypeError if the value contains circular references. - Raises a TypeError if the value contains `BigInt`s. @@ -442,7 +461,7 @@ BigInt.fromInt(0)->JSON.stringifyAny external stringifyAnyWithReplacer: ('a, (string, t) => t) => option = "JSON.stringify" /** -`stringifyAnyWithReplacerAndIndent(json, replacer, indentation)` +`stringifyAnyWithReplacerAndIndent(json, replacer, indentation)` Converts any type to a JSON string. The output will be indented. The replacer describes how the value should be transformed. It is a function which receives a key and a value. @@ -451,6 +470,7 @@ If the value contains circular references or `BigInt`s, the function will throw If you want to stringify a JSON object, use `JSON.stringifyWithReplacerAndIndent` instead. ## Examples + ```rescript let dict = Dict.fromArray([ ("foo", JSON.Encode.string("bar")), @@ -467,18 +487,17 @@ let replacer = (_, value) => { } } -JSON.stringifyAnyWithReplacerAndIndent(dict, replacer, 2) -// { -// "foo": "BAR", -// "hello": "WORLD", -// "someNumber": 42 -// } +dict +->JSON.stringifyAnyWithReplacer(replacer) +->Option.getUnsafe +->assertEqual(`{"foo":"BAR","hello":"WORLD","someNumber":42}`) -JSON.stringifyAny(() => "hello world") -// None +JSON.stringifyAny(() => "hello world")->assertEqual(None) -BigInt.fromInt(0)->JSON.stringifyAny -// exception +switch BigInt.fromInt(0)->JSON.stringifyAny { +| exception _ => assert(true) +| _ => assert(false) +} ``` ## Exceptions @@ -493,7 +512,7 @@ external stringifyAnyWithReplacerAndIndent: ('a, (string, t) => t, int) => optio "JSON.stringify" /** -`stringifyAnyWithFilter(json, filter)` +`stringifyAnyWithFilter(json, filter)` Converts any type to a JSON string. The filter is an array of keys, which should be included in the output. @@ -502,6 +521,7 @@ If the value contains circular references or `BigInt`s, the function will throw If you want to stringify a JSON object, use `JSON.stringifyWithFilter` instead. ## Examples + ```rescript let dict = Dict.fromArray([ ("foo", JSON.Encode.string("bar")), @@ -509,17 +529,19 @@ let dict = Dict.fromArray([ ("someNumber", JSON.Encode.int(42)), ]) -JSON.stringifyAnyWithFilter(dict, ["foo", "someNumber"]) -// {"foo": "bar","someNumber": 42} +dict +->JSON.stringifyAnyWithFilter(["foo", "someNumber"]) +->assertEqual(`{"foo":"bar","someNumber":42}`) -JSON.stringifyAny(() => "hello world") -// None +JSON.stringifyAny(() => "hello world")->assertEqual(None) -BigInt.fromInt(0)->JSON.stringifyAny -// exception +switch BigInt.fromInt(0)->JSON.stringifyAny { +| exception _ => assert(true) +| _ => assert(false) +} ``` -## Exceptions +## Exceptions - Raises a TypeError if the value contains circular references. - Raises a TypeError if the value contains `BigInt`s. @@ -530,7 +552,7 @@ BigInt.fromInt(0)->JSON.stringifyAny external stringifyAnyWithFilter: ('a, array) => string = "JSON.stringify" /** -`stringifyAnyWithFilterAndIndent(json, filter, indentation)` +`stringifyAnyWithFilterAndIndent(json, filter, indentation)` Converts any type to a JSON string. The output will be indented. The filter is an array of keys, which should be included in the output. @@ -539,6 +561,7 @@ If the value contains circular references or `BigInt`s, the function will throw If you want to stringify a JSON object, use `JSON.stringifyWithFilterAndIndent` instead. ## Examples + ```rescript let dict = Dict.fromArray([ ("foo", JSON.Encode.string("bar")), @@ -546,17 +569,31 @@ let dict = Dict.fromArray([ ("someNumber", JSON.Encode.int(42)), ]) -JSON.stringifyAnyWithFilterAndIndent(dict, ["foo", "someNumber"], 2) -// { -// "foo": "bar", -// "someNumber": 42 -// } - -JSON.stringifyAny(() => "hello world") -// None - -BigInt.fromInt(0)->JSON.stringifyAny -// exception +dict +->JSON.stringifyAny +->Option.getUnsafe +->assertEqual(`{"foo":"bar","hello":"world","someNumber":42}`) + +dict +->JSON.stringifyAny(~space=2) +->Option.getUnsafe +->assertEqual(`{ + "foo": "bar", + "hello": "world", + "someNumber": 42 +}`) + +dict +->JSON.stringifyAny(~replacer=Keys(["foo", "someNumber"])) +->Option.getUnsafe +->assertEqual(`{"foo":"bar","someNumber":42}`) + +JSON.stringifyAny(() => "hello world")->assertEqual(None) + +switch BigInt.fromInt(0)->JSON.stringifyAny { +| exception _ => assert(true) +| _ => assert(false) +} ``` ## Exceptions diff --git a/runtime/List.resi b/runtime/List.resi index 095a31d693..35aeb291f0 100644 --- a/runtime/List.resi +++ b/runtime/List.resi @@ -75,9 +75,12 @@ let head: t<'a> => option<'a> ## Examples ```rescript -List.headExn(list{1, 2, 3}) // 1 +List.headExn(list{1, 2, 3})->assertEqual(1) -List.headExn(list{}) // Raises an Error +switch List.headExn(list{}) { +| exception Not_found => assert(true) +| _ => assert(false) +} ``` ## Exceptions @@ -107,9 +110,12 @@ let tail: t<'a> => option> ## Examples ```rescript -List.tailExn(list{1, 2, 3}) // list{2, 3} +List.tailExn(list{1, 2, 3})->assertEqual(list{2, 3}) -List.tailExn(list{}) // Raises an Error +switch List.tailExn(list{}) { +| exception Not_found => assert(true) +| _ => assert(false) +} ``` ## Exceptions @@ -155,9 +161,14 @@ let get: (t<'a>, int) => option<'a> ```rescript let abc = list{"A", "B", "C"} -abc->List.getExn(1) // "B" +abc +->List.getExn(1) +->assertEqual("B") -abc->List.getExn(4) // Raises an Error +switch abc->List.getExn(4) { +| exception Not_found => assert(true) +| _ => assert(false) +} ``` ## Exceptions diff --git a/runtime/Map.resi b/runtime/Map.resi index f1067a8abb..a4060d6615 100644 --- a/runtime/Map.resi +++ b/runtime/Map.resi @@ -56,11 +56,25 @@ external fromArray: array<('k, 'v)> => t<'k, 'v> = "Map" Turns an iterator in the shape of `('key, 'value)` into a `Map`. ## Examples + ```rescript // Let's pretend we have an interator in the correct shape -@val external someIterator: Iterator.t<(string, int)> = "someIterator" - -let map = Map.fromIterator(someIterator) // Map.t +let iterator: Iterator.t<(string, string)> = %raw(` + (() => { + var map1 = new Map(); + + map1.set('first', '1'); + map1.set('second', '2'); + + var iterator1 = map1[Symbol.iterator](); + return iterator1; + })() +`) + +iterator +->Map.fromIterator +->Map.size +->assertEqual(2) ``` */ @new diff --git a/runtime/Null.resi b/runtime/Null.resi index 7d3f6a22fc..4758c76d8c 100644 --- a/runtime/Null.resi +++ b/runtime/Null.resi @@ -105,8 +105,17 @@ let getWithDefault: (t<'a>, 'a) => 'a `getExn(value)` raises an exception if `null`, otherwise returns the value. ```rescript -Null.getExn(Null.make(3)) // 3 -Null.getExn(Null.null) /* Raises an Error */ +Null.getExn(Null.make(3))->assertEqual(3) + +switch Null.getExn(%raw("'ReScript'")) { +| exception Invalid_argument(_) => assert(false) +| value => assertEqual(value, "ReScript") +} + +switch Null.getExn(%raw("null")) { +| exception Invalid_argument(_) => assert(true) +| _ => assert(false) +} ``` ## Exceptions diff --git a/runtime/Nullable.resi b/runtime/Nullable.resi index 30d92195e6..d03c4532a7 100644 --- a/runtime/Nullable.resi +++ b/runtime/Nullable.resi @@ -137,8 +137,20 @@ let getWithDefault: (t<'a>, 'a) => 'a `getExn(value)` raises an exception if `null` or `undefined`, otherwise returns the value. ```rescript -Nullable.getExn(Nullable.make(3)) // 3 -Nullable.getExn(Nullable.null) /* Raises an Error */ +switch Nullable.getExn(%raw("'Hello'")) { +| exception Invalid_argument(_) => assert(false) +| value => assertEqual(value, "Hello") +} + +switch Nullable.getExn(%raw("null")) { +| exception Invalid_argument(_) => assert(true) +| _ => assert(false) +} + +switch Nullable.getExn(%raw("undefined")) { +| exception Invalid_argument(_) => assert(true) +| _ => assert(false) +} ``` ## Exceptions diff --git a/runtime/Object.res b/runtime/Object.res index 434621df86..6646088c0a 100644 --- a/runtime/Object.res +++ b/runtime/Object.res @@ -186,7 +186,14 @@ See [ECMAScript Language Specification](https://tc39.es/ecma262/multipage/fundam let point = {"x": 1, "y": 2} point->Object.set("x", -7) // succeeds point->Object.seal->ignore -point->Object.set("z", 9) // fails + +try { + point->Object.set("z", 9) // fails +} catch { +| Exn.Error(_) => assert(true) +| _ => assert(false) +} + point->Object.set("x", 13) // succeeds ``` */ @@ -204,7 +211,12 @@ See [ECMAScript Language Specification](https://tc39.es/ecma262/multipage/fundam let obj = {"a": 1} obj->Object.set("b", 2) // succeeds obj->Object.preventExtensions->ignore -obj->Object.set("c", 3) // fails +try { + obj->Object.set("c", 3) // fails +} catch { +| Exn.Error(_) => assert(true) +| _ => assert(false) +} ``` */ @val @@ -219,11 +231,17 @@ See [ECMAScript Language Specification](https://tc39.es/ecma262/multipage/fundam ## Examples - ```rescript +```rescript let obj = {"a": 1} obj->Object.set("a", 2) // succeeds obj->Object.freeze->ignore -obj->Object.set("a", 3) // fails + +try { + obj->Object.set("a", 3) // fails +} catch { +| Exn.Error(_) => assert(true) +| _ => assert(false) +} ``` */ @val diff --git a/runtime/Option.resi b/runtime/Option.resi index 346eb1cd1e..3f04e48ff4 100644 --- a/runtime/Option.resi +++ b/runtime/Option.resi @@ -69,9 +69,17 @@ let forEach: (option<'a>, 'a => unit) => unit `getExn(opt, ~message=?)` returns `value` if `opt` is `Some(value)`, otherwise raises an exception with the message provided, or a generic message if no message was provided. ```rescript -Option.getExn(Some(3)) // 3 -Option.getExn(None) /* Raises an Error */ -Option.getExn(None, ~message="was None!") /* Raises an Error with the message "was None!" */ +Option.getExn(Some(3))->assertEqual(3) + +switch Option.getExn(None) { +| exception _ => assert(true) +| _ => assert(false) +} + +switch Option.getExn(None, ~message="was None!") { +| exception _ => assert(true) // Raises an Error with the message "was None!" +| _ => assert(false) +} ``` ## Exceptions diff --git a/runtime/Pervasives.res b/runtime/Pervasives.res index a19348538d..f30c2bdfc8 100644 --- a/runtime/Pervasives.res +++ b/runtime/Pervasives.res @@ -337,11 +337,12 @@ type timeoutId = Js_global.timeoutId See [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) on MDN. ## Examples + ```rescript -// Log to the console after 2 seconds (2000 milliseconds). +// Log to the console after 200 milliseconds. let timeoutId = setTimeout(() => { - Console.log("This prints in 2 seconds.") -}, 2000) + Console.log("This prints in 200 ms.") +}, 200) ``` */ @val @@ -355,11 +356,12 @@ The same as `setTimeout`, but allows you to pass a `float` instead of an `int` f See [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) on MDN. ## Examples + ```rescript -// Log to the console after 2 seconds (2000 milliseconds). +// Log to the console after 200 milliseconds. let timeoutId = setTimeoutFloat(() => { - Console.log("This prints in 2 seconds.") -}, 2000.) + Console.log("This prints in 200 ms.") +}, 200.) ``` */ @val @@ -371,6 +373,7 @@ external setTimeoutFloat: (unit => unit, float) => timeoutId = "setTimeout" See [`clearTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/clearTimeout) on MDN. ## Examples + ```rescript let timeoutId = setTimeout(() => { Console.log("This prints in 2 seconds.") @@ -396,11 +399,16 @@ type intervalId = Js_global.intervalId See [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) on MDN. ## Examples + ```rescript -// Log to the console ever 2 seconds (2000 milliseconds). +// Log to the console ever 200 ms (200 milliseconds). let intervalId = setInterval(() => { - Console.log("This prints every 2 seconds.") -}, 2000) + Console.log("This prints every 200 ms.") +}, 200) + +let timeoutId = setTimeout(() => { + clearInterval(intervalId) +}, 500) ``` */ @val @@ -414,11 +422,17 @@ The same as `setInterval`, but allows you to pass a `float` instead of an `int` See [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) on MDN. ## Examples + ```rescript -// Log to the console ever 2 seconds (2000 milliseconds). +// Log to the console ever 2 seconds (200 milliseconds). let intervalId = setIntervalFloat(() => { - Console.log("This prints every 2 seconds.") -}, 2000.) + Console.log("This prints every 200 ms") +}, 200.) + +// Stop the interval after 500 ms +let timeoutId = setTimeoutFloat(() => { + clearInterval(intervalId) +}, 500.0) ``` */ @val @@ -430,15 +444,16 @@ external setIntervalFloat: (unit => unit, float) => intervalId = "setInterval" See [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval) on MDN. ## Examples + ```rescript let intervalId = setInterval(() => { - Console.log("This prints in 2 seconds.") -}, 2000) + Console.log("This prints in 100 ms") +}, 100) -// Stop the interval after 10 seconds +// Stop the interval after 500 ms let timeoutId = setTimeout(() => { clearInterval(intervalId) -}, 10000) +}, 500) ``` */ @val @@ -564,3 +579,20 @@ type undefined<+'a> = Js.undefined<'a> type nullable<+'a> = Js.nullable<'a> let panic = Error.panic + +/** +`assertEqual(a, b)` check if `a` is equal `b`. If not raise a panic exception + +## Examples + +```rescript +list{1, 2} +->List.tailExn +->assertEqual(list{2}) +``` +*/ +let assertEqual = (a, b) => { + if a != b { + assert(false) + } +} diff --git a/runtime/Promise.resi b/runtime/Promise.resi index 5468bf9370..cb38f15c4d 100644 --- a/runtime/Promise.resi +++ b/runtime/Promise.resi @@ -37,7 +37,16 @@ See [`Promise.reject`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/R ```rescript exception TestError(string) -let p = Promise.reject(TestError("some rejected value")) +TestError("some rejected value") +->Promise.reject +->Promise.catch(v => { + switch v { + | TestError(msg) => assertEqual(msg, "some rejected value") + | _ => assert(false) + } + Promise.resolve() +}) +->ignore ``` */ @scope("Promise") diff --git a/runtime/RescriptTools.res b/runtime/RescriptTools.res index a636f55225..6ad891d51b 100644 --- a/runtime/RescriptTools.res +++ b/runtime/RescriptTools.res @@ -2,13 +2,14 @@ module Docgen = RescriptTools_Docgen /** Returns the full file system path to the `rescript-tools` binary for the current platform, side stepping the JS that wraps the CLI. - You can use this when you're already running a JS process and want to avoid the overhead of starting another one. +You can use this when you're already running a JS process and want to avoid the overhead of starting another one. - ## Examples - ```rescript - // Prints the current ReScript Tools version. - let stringifiedJson = ChildProcess.execFileSync(RescriptTools.binaryPath, ["-v"]) - ``` - */ +## Examples + +```rescript +// Prints the current ReScript Tools version. +let stringifiedJson = ChildProcess.execFileSync(RescriptTools.binaryPath, ["-v"]) +``` +*/ @module("../../cli/bin_path.js") external binaryPath: string = "rescript_tools_exe" diff --git a/runtime/Set.resi b/runtime/Set.resi index e1246faef6..b61b699074 100644 --- a/runtime/Set.resi +++ b/runtime/Set.resi @@ -55,11 +55,21 @@ external fromArray: array<'a> => t<'a> = "Set" Turns an iterator into a `Set`. ## Examples + ```rescript // Let's pretend we have an interator -@val external someIterator: Iterator.t = "someIterator" - -let set = Set.fromIterator(someIterator) // Set.t +let iterator: Iterator.t = %raw(` + (() => { + var array1 = ['a', 'b', 'c']; + var iterator1 = array1[Symbol.iterator](); + return iterator1 + })() +`) + +iterator +->Set.fromIterator +->Set.size +->assertEqual(3) ``` */ @new diff --git a/runtime/String.resi b/runtime/String.resi index c9121179fb..23537a1029 100644 --- a/runtime/String.resi +++ b/runtime/String.resi @@ -453,13 +453,11 @@ See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for d ## Examples ```rescript -let string1 = "\uFB00" -let string2 = "\u0066\u0066" -Console.log(string1 === string2) // false +let string1 = "\u00F1" +let string2 = "\u006E\u0303" -let normalizeString1 = String.normalize(string1) -let normalizeString2 = String.normalize(string2) -assert(normalizeString1 === normalizeString2) +assert(string1 != string2) // true +assertEqual(String.normalize(string1), String.normalize(string2)) ``` */ @send diff --git a/scripts/test.js b/scripts/test.js index 8a88795650..3b5c8ca39e 100644 --- a/scripts/test.js +++ b/scripts/test.js @@ -12,6 +12,7 @@ let ounitTest = false; let mochaTest = false; let bsbTest = false; let formatTest = false; +let runtimeDocstrings = false; if (process.argv.includes("-ounit")) { ounitTest = true; @@ -29,11 +30,16 @@ if (process.argv.includes("-format")) { formatTest = true; } +if (process.argv.includes("-docstrings")) { + runtimeDocstrings = true; +} + if (process.argv.includes("-all")) { ounitTest = true; mochaTest = true; bsbTest = true; formatTest = true; + runtimeDocstrings = true; } async function runTests() { @@ -120,6 +126,26 @@ async function runTests() { process.exit(1); } } + + if (runtimeDocstrings) { + if (process.platform === "win32") { + console.log(`Skipping docstrings tests on ${process.platform}`); + } else { + console.log("Running runtime docstrings tests"); + cp.execSync(`${rescript_exe} build`, { + cwd: path.join(__dirname, "..", "tests/docstrings_examples"), + stdio: [0, 1, 2], + }); + // Ignore some tests not supported by node v18 + // cp.execSync( + // `node ${path.join("tests", "docstrings_examples", "DocTest.res.mjs")} --ignore-runtime-tests "Array.toReversed, Array.toSorted, Promise.withResolvers, Set.union, Set.isSupersetOf, Set.isSubsetOf, Set.isDisjointFrom, Set.intersection, Set.symmetricDifference, Set.difference"`, + // { + // cwd: path.join(__dirname, ".."), + // stdio: [0, 1, 2], + // }, + // ); + } + } } runTests(); diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index a4855bd813..4e3382d9a9 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -10,7 +10,7 @@ Path MyList.m "kind": 12, "tags": [], "detail": "(t<'a>, 'a => 'b) => t<'b>", - "documentation": {"kind": "markdown", "value": "\nEquivalent to:\n\n```res\nmap(someList, f)->reverse\n```\n\n## Examples\n\n```rescript\nlist{3, 4, 5}->Belt.List.mapReverse(x => x * x) /* list{25, 16, 9} */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nEquivalent to `Belt.List.map(someList, f)->Belt.List.reverse`\n\n## Examples\n\n```rescript\nlist{3, 4, 5}\n->Belt.List.mapReverse(x => x * x)\n->assertEqual(list{25, 16, 9})\n```\n"} }, { "label": "makeBy", "kind": 12, @@ -91,25 +91,25 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, array<'a>) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`concat(array1, array2)` concatenates the two arrays, creating a new array.\n\nSee [`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) on MDN.\n\n## Examples\n```rescript\nlet array1 = [\"hi\", \"hello\"]\nlet array2 = [\"yay\", \"wehoo\"]\n\nlet someArray = array1->Array.concat(array2)\n\nConsole.log(someArray) // [\"hi\", \"hello\", \"yay\", \"wehoo\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`concat(array1, array2)` concatenates the two arrays, creating a new array.\n\nSee [`Array.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) on MDN.\n\n## Examples\n\n```rescript\nlet array1 = [\"hi\", \"hello\"]\nlet array2 = [\"yay\", \"wehoo\"]\n\nlet someArray = array1->Array.concat(array2)\n\nsomeArray->assertEqual([\"hi\", \"hello\", \"yay\", \"wehoo\"])\n```\n"} }, { "label": "filterMap", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => option<'b>) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`filterMap(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\nConsole.log(\n array->Array.filterMap(item =>\n switch item {\n | \"Hello\" => Some(item->String.length)\n | _ => None\n }\n ),\n) // [5]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`filterMap(array, fn)`\n\nCalls `fn` for each element and returns a new array containing results of the `fn` calls which are not `None`.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]\n->Array.filterMap(item =>\n switch item {\n | \"Hello\" => Some(item->String.length)\n | _ => None\n }\n)\n->assertEqual([5])\n\n[1, 2, 3, 4, 5, 6]\n->Array.filterMap(n => mod(n, 2) == 0 ? Some(n * n) : None)\n->assertEqual([4, 16, 36])\n\nArray.filterMap([1, 2, 3, 4, 5, 6], _ => None)->assertEqual([])\n\nArray.filterMap([], n => mod(n, 2) == 0 ? Some(n * n) : None)->assertEqual([])\n```\n"} }, { "label": "shift", "kind": 12, "tags": [], "detail": "array<'a> => option<'a>", - "documentation": {"kind": "markdown", "value": "\n`shift(array)` removes the first item in the array, and returns it.\n\nBeware this will *mutate* the array.\n\nSee [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nlet lastItem = someArray->Array.shift // \"hi\"\n\nConsole.log(someArray) // [\"hello\"]. Notice first item is gone.\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`shift(array)` removes the first item in the array, and returns it.\n\nBeware this will *mutate* the array.\n\nSee [`Array.shift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\n\nsomeArray\n->Array.shift\n->assertEqual(Some(\"hi\"))\n\nsomeArray->assertEqual([\"hello\"]) // Notice first item is gone.\n```\n"} }, { "label": "findMap", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => option<'b>) => option<'b>", - "documentation": {"kind": "markdown", "value": "\n `findMap(arr, fn)`\n\n Calls `fn` for each element and returns the first value from `fn` that is `Some(_)`.\n Otherwise returns `None`\n\n ```res example\n Array.findMap([1, 2, 3], n => mod(n, 2) == 0 ? Some(n - 2) : None) == Some(0) // true\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`findMap(arr, fn)`\n\nCalls `fn` for each element and returns the first value from `fn` that is `Some(_)`.\nOtherwise returns `None`\n\n## Examples\n\n```rescript\nArray.findMap([1, 2, 3], n => mod(n, 2) == 0 ? Some(n - 2) : None)->assertEqual(Some(0))\n\nArray.findMap([1, 2, 3, 4, 5, 6], n => mod(n, 2) == 0 ? Some(n - 8) : None)->assertEqual(Some(-6))\n\nArray.findMap([1, 2, 3, 4, 5, 6], _ => None)->assertEqual(None)\n\nArray.findMap([], n => mod(n, 2) == 0 ? Some(n * n) : None)->assertEqual(None)\n```\n"} }, { "label": "concatMany", "kind": 12, @@ -121,31 +121,31 @@ Path Array. "kind": 12, "tags": [1], "detail": "(array, string) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `join` instead\n\n\n`joinWith(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Array items must be strings, to join number or other arrays, use `joinWithUnsafe`. Under the hood this will run JavaScript's `toString` on all the array items.\n\n## Examples\n```rescript\nlet array = [\"One\", \"Two\", \"Three\"]\n\nConsole.log(array->Array.joinWith(\" -- \")) // One -- Two -- Three\n```\n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `join` instead\n\n\n`joinWith(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Array items must be strings, to join number or other arrays, use `joinWithUnsafe`. Under the hood this will run JavaScript's `toString` on all the array items.\n\n## Examples\n\n```rescript\n[\"One\", \"Two\", \"Three\"]\n->Array.joinWith(\" -- \")\n->assertEqual(\"One -- Two -- Three\")\n```\n"} }, { "label": "joinWithUnsafe", "kind": 12, "tags": [1], "detail": "(array<'a>, string) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `joinUnsafe` instead\n\n\n`joinWithUnsafe(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Under the hood this will run JavaScript's `toString` on all the array items.\n\n## Examples\n```rescript\nlet array = [1, 2, 3]\n\nConsole.log(array->Array.joinWithUnsafe(\" -- \")) // 1 -- 2 -- 3\n```\n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `joinUnsafe` instead\n\n\n`joinWithUnsafe(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Under the hood this will run JavaScript's `toString` on all the array items.\n\n## Examples\n\n```rescript\n[1, 2, 3]\n->Array.joinWithUnsafe(\" -- \")\n->assertEqual(\"1 -- 2 -- 3\")\n```\n"} }, { "label": "reduceRight", "kind": 12, "tags": [], "detail": "(array<'a>, 'b, ('b, 'a) => 'b) => 'b", - "documentation": {"kind": "markdown", "value": "\n `reduceRight(xs, init, fn)`\n\n Works like `Array.reduce`; except that function `fn` is applied to each item of `xs` from the last back to the first.\n\n ```res example\n Array.reduceRight([\"a\", \"b\", \"c\", \"d\"], \"\", (a, b) => a ++ b) == \"dcba\"\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`reduceRight(xs, init, fn)`\n\nWorks like `Array.reduce`; except that function `fn` is applied to each item of `xs` from the last back to the first.\n\n## Examples\n\n```rescript\nArray.reduceRight([\"a\", \"b\", \"c\", \"d\"], \"\", (a, b) => a ++ b)->assertEqual(\"dcba\")\n\nArray.reduceRight([1, 2, 3], list{}, List.add)->assertEqual(list{1, 2, 3})\n\nArray.reduceRight([], list{}, List.add)->assertEqual(list{})\n```\n"} }, { "label": "reduceRightWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, 'b, ('b, 'a, int) => 'b) => 'b", - "documentation": {"kind": "markdown", "value": "\n `reduceRightWithIndex(xs, init, fn)`\n\n Like `reduceRight`, but with an additional index argument on the callback function.\n\n ```res example\n Array.reduceRightWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i) == 16\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`reduceRightWithIndex(xs, init, fn)`\n\nLike `reduceRight`, but with an additional index argument on the callback function.\n\n## Examples\n\n```rescript\nArray.reduceRightWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i)->assertEqual(16)\n\nArray.reduceRightWithIndex([], list{}, (acc, v, i) => list{v + i, ...acc})->assertEqual(list{})\n```\n"} }, { "label": "toShuffled", "kind": 12, "tags": [], "detail": "array<'a> => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`toShuffled(array)` returns a new array with all items in `array` in a random order.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet shuffledArray = array->Array.toShuffled\n\nConsole.log(shuffledArray)\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`toShuffled(array)` returns a new array with all items in `array` in a random order.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet shuffledArray = array->Array.toShuffled\nConsole.log(shuffledArray)\n\nArray.toShuffled([1, 2, 3])\n->Array.length\n->assertEqual(3)\n```\n"} }, { "label": "getSymbol", "kind": 12, @@ -163,73 +163,73 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, 'a => bool) => option", - "documentation": {"kind": "markdown", "value": "\n`findIndexOpt(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.\n\nReturns `None` if no item matches.\n\nSee [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN.\n\n## Examples\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\nswitch array->Array.findIndexOpt(item => item == ReScript) {\n| None => Console.log(\"Ahh, no ReScript...\")\n| Some(index) => Console.log(\"Yay, ReScript at index \" ++ Int.toString(index))\n}\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`findIndexOpt(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.\n\nReturns `None` if no item matches.\n\nSee [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN.\n\n## Examples\n\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\narray\n->Array.findIndexOpt(item => item == ReScript)\n->assertEqual(Some(0))\n```\n"} }, { "label": "shuffle", "kind": 12, "tags": [], "detail": "array<'a> => unit", - "documentation": {"kind": "markdown", "value": "\n`shuffle(array)` randomizes the position of all items in `array`.\n\nBeware this will *mutate* the array.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\narray->Array.shuffle\n\nConsole.log(array)\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`shuffle(array)` randomizes the position of all items in `array`.\n\nBeware this will *mutate* the array.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\narray->Array.shuffle\nConsole.log(array)\n\nlet array2 = [1, 2, 3]\narray2->Array.shuffle\n\narray2\n->Array.length\n->assertEqual(3)\n```\n"} }, { "label": "copy", "kind": 12, "tags": [], "detail": "array<'a> => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`copy(array)` makes a copy of the array with the items in it, but does not make copies of the items themselves.\n\n## Examples\n```rescript\nlet myArray = [1, 2, 3]\nlet copyOfMyArray = myArray->Array.copy\n\nConsole.log(copyOfMyArray) // [1, 2, 3]\nConsole.log(myArray === copyOfMyArray) // false\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`copy(array)` makes a copy of the array with the items in it, but does not make copies of the items themselves.\n\n## Examples\n\n```rescript\nlet myArray = [1, 2, 3]\nlet copyOfMyArray = myArray->Array.copy\n\ncopyOfMyArray->assertEqual([1, 2, 3])\nassertEqual(myArray === copyOfMyArray, false)\n```\n"} }, { "label": "setUnsafe", "kind": 12, "tags": [], "detail": "(array<'a>, int, 'a) => unit", - "documentation": {"kind": "markdown", "value": "\n`setUnsafe(array, index, item)` sets the provided `item` at `index` of `array`.\n\nBeware this will *mutate* the array, and is *unsafe*.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\narray->Array.setUnsafe(1, \"Hello\")\n\nConsole.log(array[1]) // \"Hello\"\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`setUnsafe(array, index, item)` sets the provided `item` at `index` of `array`.\n\nBeware this will *mutate* the array, and is *unsafe*.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\narray->Array.setUnsafe(1, \"Hello\")\n\nassertEqual(array[1], Some(\"Hello\"))\n```\n"} }, { "label": "findIndexWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => bool) => int", - "documentation": {"kind": "markdown", "value": "\n`findIndexWithIndex(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.\n\nReturns `-1` if the item does not exist. Consider using `Array.findIndexOpt` if you want an option instead (where `-1` would be `None`).\n\nSee [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN.\n\n## Examples\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, JavaScript]\n\nlet isReScriptFirst = array->Array.findIndexWithIndex((item, index) => index === 0 && item == ReScript)\nlet isTypeScriptFirst = array->Array.findIndexWithIndex((item, index) => index === 0 && item == TypeScript)\n\nConsole.log(isReScriptFirst) // 0\nConsole.log(isTypeScriptFirst) // -1\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`findIndexWithIndex(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.\n\nReturns `-1` if the item does not exist. Consider using `Array.findIndexOpt` if you want an option instead (where `-1` would be `None`).\n\nSee [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN.\n\n## Examples\n\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, JavaScript]\n\nlet isReScriptFirst = array->Array.findIndexWithIndex((item, index) => index === 0 && item == ReScript)\nlet isTypeScriptFirst = array->Array.findIndexWithIndex((item, index) => index === 0 && item == TypeScript)\n\nassertEqual(isReScriptFirst, 0)\nassertEqual(isTypeScriptFirst, -1)\n```\n"} }, { "label": "someWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => bool) => bool", - "documentation": {"kind": "markdown", "value": "\n`someWithIndex(array, checker)` returns true if running the provided `checker` function on any element in `array` returns true.\n\nSee [`Array.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\nConsole.log(array->Array.someWithIndex((greeting, index) => greeting === \"Hello\" && index === 0)) // true\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`someWithIndex(array, checker)` returns true if running the provided `checker` function on any element in `array` returns true.\n\nSee [`Array.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray\n->Array.someWithIndex((greeting, index) => greeting === \"Hello\" && index === 0)\n->assertEqual(true)\n```\n"} }, { "label": "slice", "kind": 12, "tags": [], "detail": "(array<'a>, ~start: int, ~end: int) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`slice(array, ~start, ~end)` creates a new array of items copied from `array` from `start` until (but not including) `end`.\n\nSee [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN.\n\n## Examples\n```rescript\nlet myArray = [1, 2, 3, 4]\n\nConsole.log(myArray->Array.slice(~start=1, ~end=3)) // [2, 3]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`slice(array, ~start, ~end)` creates a new array of items copied from `array` from `start` until (but not including) `end`.\n\nSee [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN.\n\n## Examples\n\n```rescript\n[1, 2, 3, 4]\n->Array.slice(~start=1, ~end=3)\n->assertEqual([2, 3])\n```\n"} }, { "label": "fillToEnd", "kind": 12, "tags": [], "detail": "(array<'a>, 'a, ~start: int) => unit", - "documentation": {"kind": "markdown", "value": "\n`fillToEnd(array, value, ~start)` fills `array` with `value` from the `start` index.\n\nBeware this will *mutate* the array.\n\nSee [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN.\n\n## Examples\n```rescript\nlet myArray = [1, 2, 3, 4]\nmyArray->Array.fillToEnd(9, ~start=1)\n\nConsole.log(myArray) // [1, 9, 9, 9]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`fillToEnd(array, value, ~start)` fills `array` with `value` from the `start` index.\n\nBeware this will *mutate* the array.\n\nSee [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN.\n\n## Examples\n\n```rescript\nlet myArray = [1, 2, 3, 4]\nmyArray->Array.fillToEnd(9, ~start=1)\nmyArray->assertEqual([1, 9, 9, 9])\n```\n"} }, { "label": "includes", "kind": 12, "tags": [], "detail": "(array<'a>, 'a) => bool", - "documentation": {"kind": "markdown", "value": "\n`includes(array, item)` checks whether `array` includes `item`, by doing a [strict check for equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality).\n\nSee [`Array.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) on MDN.\n\n## Examples\n```rescript\nConsole.log([1, 2]->Array.includes(1)) // true\nConsole.log([1, 2]->Array.includes(3)) // false\nConsole.log([{\"language\": \"ReScript\"}]->Array.includes({\"language\": \"ReScript\"})) // false, because of strict equality\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`includes(array, item)` checks whether `array` includes `item`, by doing a [strict check for equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality).\n\nSee [`Array.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) on MDN.\n\n## Examples\n\n```rescript\n[1, 2]->Array.includes(1)->assertEqual(true)\n[1, 2]->Array.includes(3)->assertEqual(false)\n\n[{\"language\": \"ReScript\"}]\n->Array.includes({\"language\": \"ReScript\"})\n->assertEqual(false) // false, because of strict equality\n```\n"} }, { "label": "fromInitializer", "kind": 12, "tags": [], "detail": "(~length: int, int => 'a) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n `fromInitializer(~length, f)`\n\n Creates an array of length `length` initialized with the value returned from `f ` for each index.\n\n ```res example\n Array.fromInitializer(~length=3, i => i + 3) == [3, 4, 5]\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`fromInitializer(~length, f)`\n\nCreates an array of length `length` initialized with the value returned from `f ` for each index.\n\n## Examples\n\n```rescript\nArray.fromInitializer(~length=3, i => i + 3)->assertEqual([3, 4, 5])\n\nArray.fromInitializer(~length=7, i => i + 3)->assertEqual([3, 4, 5, 6, 7, 8, 9])\n```\n"} }, { "label": "find", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => bool) => option<'a>", - "documentation": {"kind": "markdown", "value": "\n`find(array, checker)` returns the first element of `array` where the provided `checker` function returns true.\n\nSee [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN.\n\n## Examples\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\nswitch array->Array.find(item => item == ReScript) {\n| None => Console.log(\"No item...\")\n| Some(_) => Console.log(\"Yay, ReScript!\")\n}\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`find(array, checker)` returns the first element of `array` where the provided `checker` function returns true.\n\nSee [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN.\n\n## Examples\n\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\narray\n->Array.find(item => item == ReScript)\n->assertEqual(Some(ReScript))\n```\n"} }, { "label": "make", "kind": 12, "tags": [], "detail": "(~length: int, 'a) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n `make(~length, init)`\n\n Creates an array of length `length` initialized with the value of `init`.\n\n ```res example\n Array.make(~length=3, #apple) == [#apple, #apple, #apple]\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`make(~length, init)`\n\nCreates an array of length `length` initialized with the value of `init`.\n\n## Examples\n\n```rescript\nArray.make(~length=3, #apple)->assertEqual([#apple, #apple, #apple])\nArray.make(~length=6, 7)->assertEqual([7, 7, 7, 7, 7, 7])\n```\n"} }, { "label": "lastIndexOfFrom", "kind": 12, @@ -253,31 +253,31 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, ('a, 'a) => Ordering.t) => unit", - "documentation": {"kind": "markdown", "value": "\n`sort(array, comparator)` sorts `array` in-place using the `comparator` function.\n\nBeware this will *mutate* the array.\n\nSee [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN.\n\n## Examples\n```rescript\nlet someArray = [3, 2, 1]\nsomeArray->Array.sort((a, b) => float(a - b))\n\nConsole.log(someArray) // [1, 2, 3]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`sort(array, comparator)` sorts `array` in-place using the `comparator` function.\n\nBeware this will *mutate* the array.\n\nSee [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN.\n\n## Examples\n\n```rescript\nlet array = [3, 2, 1]\narray->Array.sort((a, b) => float(a - b))\narray->assertEqual([1, 2, 3])\n```\n"} }, { "label": "length", "kind": 12, "tags": [], "detail": "array<'a> => int", - "documentation": {"kind": "markdown", "value": "\n`length(array)` returns the length of (i.e. number of items in) the array.\n\nSee [`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\n\nConsole.log(someArray->Array.length) // 2\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`length(array)` returns the length of (i.e. number of items in) the array.\n\nSee [`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\n\nsomeArray\n->Array.length\n->assertEqual(2)\n```\n"} }, { "label": "every", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => bool) => bool", - "documentation": {"kind": "markdown", "value": "\n`every(array, predicate)` returns true if `predicate` returns true for all items in `array`.\n\nSee [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN.\n\n## Examples\n```rescript\nlet array = [1, 2, 3, 4]\n\nConsole.log(array->Array.every(num => num <= 4)) // true\nConsole.log(array->Array.every(num => num === 1)) // false\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`every(array, predicate)` returns true if `predicate` returns true for all items in `array`.\n\nSee [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN.\n\n## Examples\n\n```rescript\nlet array = [1, 2, 3, 4]\n\narray\n->Array.every(num => num <= 4)\n->assertEqual(true)\n\narray\n->Array.every(num => num === 1)\n->assertEqual(false)\n```\n"} }, { "label": "flat", "kind": 12, "tags": [], "detail": "array> => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`flat(arrays)` concatenates an array of arrays into a single array.\n\nSee [`Array.flat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) on MDN.\n\n## Examples\n```rescript\nConsole.log([[1], [2], [3, 4]]->Array.flat) // [1, 2, 3, 4]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`flat(arrays)` concatenates an array of arrays into a single array.\n\nSee [`Array.flat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) on MDN.\n\n## Examples\n\n```rescript\n[[1], [2], [3, 4]]\n->Array.flat\n->assertEqual([1, 2, 3, 4])\n```\n"} }, { "label": "map", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => 'b) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`map(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray = array->Array.map(greeting => greeting ++ \" to you\")\n\nConsole.log(mappedArray) // [\"Hello to you\", \"Hi to you\", \"Good bye to you\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`map(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray = array->Array.map(greeting => greeting ++ \" to you\")\n\nassertEqual(mappedArray, [\"Hello to you\", \"Hi to you\", \"Good bye to you\"])\n```\n"} }, { "label": "with", "kind": 12, @@ -295,7 +295,7 @@ Path Array. "kind": 12, "tags": [], "detail": "array<'a> => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`toReversed(array)` creates a new array with all items from `array` in reversed order.\n\nSee [`Array.toReversed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nlet reversed = someArray->Array.toReversed\n\nConsole.log(reversed) // [\"hello\", \"h1\"]\nConsole.log(someArray) // [\"h1\", \"hello\"]. Original unchanged\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`toReversed(array)` creates a new array with all items from `array` in reversed order.\n\nSee [`Array.toReversed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nlet reversed = someArray->Array.toReversed\n\nreversed->assertEqual([\"hello\", \"hi\"])\nsomeArray->assertEqual([\"h1\", \"hello\"]) // Original unchanged\n```\n"} }, { "label": "copyWithin", "kind": 12, @@ -307,31 +307,31 @@ Path Array. "kind": 12, "tags": [], "detail": "array<'a> => string", - "documentation": {"kind": "markdown", "value": "\n`toString(array)` stringifies `array` by running `toString` on all of the array elements and joining them with \",\".\n\nSee [`Array.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) on MDN.\n\n## Examples\n```rescript\nlet array = [1, 2, 3, 4]\n\nConsole.log(array->Array.toString) // \"1,2,3,4\"\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`toString(array)` stringifies `array` by running `toString` on all of the array elements and joining them with \",\".\n\nSee [`Array.toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString) on MDN.\n\n## Examples\n\n```rescript\n[1, 2, 3, 4]\n->Array.toString\n->assertEqual(\"1,2,3,4\")\n```\n"} }, { "label": "everyWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => bool) => bool", - "documentation": {"kind": "markdown", "value": "\n`everyWithIndex(array, checker)` returns true if all items in `array` returns true when running the provided `checker` function.\n\nSee [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN.\n\n## Examples\n```rescript\nlet array = [1, 2, 3, 4]\n\nConsole.log(array->Array.everyWithIndex((num, index) => index < 2 && num <= 2)) // true\nConsole.log(array->Array.everyWithIndex((num, index) => index < 2 && num >= 2)) // false\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`everyWithIndex(array, checker)` returns true if all items in `array` returns true when running the provided `checker` function.\n\nSee [`Array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) on MDN.\n\n## Examples\n\n```rescript\nlet array = [1, 2, 3, 4]\n\narray\n->Array.everyWithIndex((num, index) => index < 5 && num <= 4)\n->assertEqual(true)\n\narray\n->Array.everyWithIndex((num, index) => index < 2 && num >= 2)\n->assertEqual(false)\n```\n"} }, { "label": "fill", "kind": 12, "tags": [], "detail": "(array<'a>, 'a, ~start: int, ~end: int) => unit", - "documentation": {"kind": "markdown", "value": "\n`fill(array, value, ~start, ~end)` fills `array` with `value` from `start` to `end`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN.\n\n## Examples\n```rescript\nlet myArray = [1, 2, 3, 4]\nmyArray->Array.fill(9, ~start=1, ~end=2)\n\nConsole.log(myArray) // [1, 9, 9, 4]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`fill(array, value, ~start, ~end)` fills `array` with `value` from `start` to `end`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN.\n\n## Examples\n\n```rescript\nlet myArray = [1, 2, 3, 4]\n\nmyArray->Array.fill(9, ~start=1, ~end=3)\n\nmyArray->assertEqual([1, 9, 9, 4])\n```\n"} }, { "label": "findWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => bool) => option<'a>", - "documentation": {"kind": "markdown", "value": "\n`findWithIndex(array, checker)` returns the first element of `array` where the provided `checker` function returns true.\n\nSee [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN.\n\n## Examples\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [TypeScript, JavaScript, ReScript]\n\nswitch array->Array.findWithIndex((item, index) => index > 1 && item == ReScript) {\n| None => Console.log(\"No item...\")\n| Some(_) => Console.log(\"Yay, ReScript exists in a later position!\")\n}\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`findWithIndex(array, checker)` returns the first element of `array` where the provided `checker` function returns true.\n\nSee [`Array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) on MDN.\n\n## Examples\n\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [TypeScript, JavaScript, ReScript]\n\narray\n->Array.findWithIndex((item, index) => index > 1 && item == ReScript)\n->assertEqual(Some(ReScript))\n```\n"} }, { "label": "reverse", "kind": 12, "tags": [], "detail": "array<'a> => unit", - "documentation": {"kind": "markdown", "value": "\n`reverse(array)` reverses the order of the items in `array`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.reverse\n\nConsole.log(someArray) // [\"hello\", \"h1\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`reverse(array)` reverses the order of the items in `array`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.reverse\n\nsomeArray->assertEqual([\"hello\", \"hi\"])\n```\n"} }, { "label": "getUnsafe", "kind": 12, @@ -343,7 +343,7 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, array<'a>) => unit", - "documentation": {"kind": "markdown", "value": "\n`unshiftMany(array, itemsArray)` inserts many new items to the start of the array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.unshiftMany([\"yay\", \"wehoo\"])\n\nConsole.log(someArray) // [\"yay\", \"wehoo\", \"hi\", \"hello\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`unshiftMany(array, itemsArray)` inserts many new items to the start of the array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.unshiftMany([\"yay\", \"wehoo\"])\nsomeArray->assertEqual([\"yay\", \"wehoo\", \"hi\", \"hello\"])\n```\n"} }, { "label": "lastIndexOf", "kind": 12, @@ -355,7 +355,7 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, 'a => bool) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`filter(array, checker)` returns a new array containing all elements from `array` for which the provided `checker` function returns true.\n\nSee [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN.\n\n## Examples\n```rescript\nlet array = [1, 2, 3, 4]\n\nConsole.log(array->Array.filter(num => num > 2)) // [3, 4]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`filter(array, checker)` returns a new array containing all elements from `array` for which the provided `checker` function returns true.\n\nSee [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN.\n\n## Examples\n\n```rescript\n[1, 2, 3, 4]\n->Array.filter(num => num > 2)\n->assertEqual([3, 4])\n```\n"} }, { "label": "compare", "kind": 12, @@ -367,13 +367,13 @@ Path Array. "kind": 12, "tags": [], "detail": "(array, string) => string", - "documentation": {"kind": "markdown", "value": "\n`join(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Array items must be strings, to join number or other arrays, use `joinUnsafe`. Under the hood this will run JavaScript's `toString` on all the array items.\n\nSee [Array.join](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join)\n\n## Examples\n```rescript\nlet array = [\"One\", \"Two\", \"Three\"]\n\nConsole.log(array->Array.join(\" -- \")) // One -- Two -- Three\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`join(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Array items must be strings, to join number or other arrays, use `joinUnsafe`. Under the hood this will run JavaScript's `toString` on all the array items.\n\nSee [Array.join](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join)\n\n## Examples\n\n```rescript\n[\"One\", \"Two\", \"Three\"]\n->Array.join(\" -- \")\n->assertEqual(\"One -- Two -- Three\")\n```\n"} }, { "label": "last", "kind": 12, "tags": [], "detail": "array<'a> => option<'a>", - "documentation": {"kind": "markdown", "value": "\n`last(array)` returns the last element of `array`.\n\nReturns `None` if the array is empty.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray->Array.last == Some(\"Good bye\") // true\n[]->Array.last == None // true\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`last(array)` returns the last element of `array`.\n\nReturns `None` if the array is empty.\n\n## Examples\n\n```rescript\n[\"Hello\", \"Hi\", \"Good bye\"]\n->Array.last\n->assertEqual(Some(\"Good bye\"))\n\n[]\n->Array.last\n->assertEqual(None)\n```\n"} }, { "label": "isArray", "kind": 12, @@ -385,25 +385,25 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, 'a) => option", - "documentation": {"kind": "markdown", "value": "\n`indexOfOpt(array, item)` returns an option of the index of the provided `item` in `array`. Uses [strict check for equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) when comparing items.\n\nSee [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) on MDN.\n\n## Examples\n```rescript\nConsole.log([1, 2]->Array.indexOfOpt(2)) // Some(1)\nConsole.log([1, 2]->Array.indexOfOpt(3)) // None\nConsole.log([{\"language\": \"ReScript\"}]->Array.indexOfOpt({\"language\": \"ReScript\"})) // None, because of strict equality\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`indexOfOpt(array, item)` returns an option of the index of the provided `item` in `array`. Uses [strict check for equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) when comparing items.\n\nSee [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) on MDN.\n\n## Examples\n\n```rescript\n[1, 2]->Array.indexOfOpt(2)->assertEqual(Some(1))\n[1, 2]->Array.indexOfOpt(3)->assertEqual(None)\n[{\"language\": \"ReScript\"}]\n->Array.indexOfOpt({\"language\": \"ReScript\"})\n->assertEqual(None) // None, because of strict equality\n```\n"} }, { "label": "forEachWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => unit) => unit", - "documentation": {"kind": "markdown", "value": "\n`forEachWithIndex(array, fn)` runs the provided `fn` on every element of `array`.\n\nSee [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray->Array.forEachWithIndex((item, index) => {\n Console.log(\"At item \" ++ Int.toString(index) ++ \": \" ++ item)\n})\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`forEachWithIndex(array, fn)` runs the provided `fn` on every element of `array`.\n\nSee [`Array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray->Array.forEachWithIndex((item, index) => {\n Console.log(\"At item \" ++ Int.toString(index) ++ \": \" ++ item)\n})\n```\n"} }, { "label": "reduce", "kind": 12, "tags": [], "detail": "(array<'a>, 'b, ('b, 'a) => 'b) => 'b", - "documentation": {"kind": "markdown", "value": "\n `reduce(xs, init, fn)`\n\n Applies `fn` to each element of `xs` from beginning to end. Function `fn` has two parameters: the item from the list and an “accumulator”; which starts with a value of `init`. `reduce` returns the final value of the accumulator.\n\n ```res example\n Array.reduce([2, 3, 4], 1, (a, b) => a + b) == 10\n\n Array.reduce([\"a\", \"b\", \"c\", \"d\"], \"\", (a, b) => a ++ b) == \"abcd\"\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`reduce(xs, init, fn)`\n\nApplies `fn` to each element of `xs` from beginning to end. Function `fn` has two parameters: the item from the list and an “accumulator”; which starts with a value of `init`. `reduce` returns the final value of the accumulator.\n\n## Examples\n\n```rescript\nArray.reduce([2, 3, 4], 1, (a, b) => a + b)->assertEqual(10)\n\nArray.reduce([\"a\", \"b\", \"c\", \"d\"], \"\", (a, b) => a ++ b)->assertEqual(\"abcd\")\n\n[1, 2, 3]\n->Array.reduce(list{}, List.add)\n->assertEqual(list{3, 2, 1})\n\nArray.reduce([], list{}, List.add)->assertEqual(list{})\n```\n"} }, { "label": "sliceToEnd", "kind": 12, "tags": [], "detail": "(array<'a>, ~start: int) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`sliceToEnd(array, start)` creates a new array from `array`, with all items from `array` starting from `start`.\n\nSee [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN.\n\n## Examples\n```rescript\nlet myArray = [1, 2, 3, 4]\n\nConsole.log(myArray->Array.sliceToEnd(~start=1)) // [2, 3, 4]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`sliceToEnd(array, start)` creates a new array from `array`, with all items from `array` starting from `start`.\n\nSee [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN.\n\n## Examples\n\n```rescript\n[1, 2, 3, 4]\n->Array.sliceToEnd(~start=1)\n->assertEqual([2, 3, 4])\n```\n"} }, { "label": "fromArrayLikeWithMap", "kind": 12, @@ -415,25 +415,25 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, 'a) => unit", - "documentation": {"kind": "markdown", "value": "\n`fillAll(array, value)` fills the entire `array` with `value`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN.\n\n## Examples\n```rescript\nlet myArray = [1, 2, 3, 4]\nmyArray->Array.fillAll(9)\n\nConsole.log(myArray) // [9, 9, 9, 9]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`fillAll(array, value)` fills the entire `array` with `value`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.fill`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill) on MDN.\n\n## Examples\n\n```rescript\nlet myArray = [1, 2, 3, 4]\nmyArray->Array.fillAll(9)\nmyArray->assertEqual([9, 9, 9, 9])\n```\n"} }, { "label": "set", "kind": 12, "tags": [], "detail": "(array<'a>, int, 'a) => unit", - "documentation": {"kind": "markdown", "value": "\n`set(array, index, item)` sets the provided `item` at `index` of `array`.\n\nBeware this will *mutate* the array.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\narray->Array.set(1, \"Hello\")\n\nConsole.log(array[1]) // \"Hello\"\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`set(array, index, item)` sets the provided `item` at `index` of `array`.\n\nBeware this will *mutate* the array.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\narray->Array.set(1, \"Hello\")\n\narray[1]->assertEqual(Some(\"Hello\"))\n```\n"} }, { "label": "filterWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => bool) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`filterWithIndex(array, checker)` returns a new array containing all elements from `array` for which the provided `checker` function returns true.\n\nSee [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN.\n\n## Examples\n```rescript\nlet array = [1, 2, 3, 4]\n\nConsole.log(array->Array.filterWithIndex((num, index) => index === 0 || num === 2)) // [1, 2]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`filterWithIndex(array, checker)` returns a new array containing all elements from `array` for which the provided `checker` function returns true.\n\nSee [`Array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) on MDN.\n\n## Examples\n\n```rescript\n[1, 2, 3, 4]\n->Array.filterWithIndex((num, index) => index === 0 || num === 2)\n->assertEqual([1, 2])\n```\n"} }, { "label": "findIndex", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => bool) => int", - "documentation": {"kind": "markdown", "value": "\n`findIndex(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.\n\nReturns `-1` if the item does not exist. Consider using `Array.findIndexOpt` if you want an option instead (where `-1` would be `None`).\n\nSee [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN.\n\n## Examples\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, JavaScript]\n\nConsole.log(array->Array.findIndex(item => item == ReScript)) // 0\nConsole.log(array->Array.findIndex(item => item == TypeScript)) // -1\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`findIndex(array, checker)` returns the index of the first element of `array` where the provided `checker` function returns true.\n\nReturns `-1` if the item does not exist. Consider using `Array.findIndexOpt` if you want an option instead (where `-1` would be `None`).\n\nSee [`Array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) on MDN.\n\n## Examples\n\n```rescript\ntype languages = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, JavaScript]\n\narray\n->Array.findIndex(item => item == ReScript)\n->assertEqual(0)\n\narray->Array.findIndex(item => item == TypeScript)\n->assertEqual(-1)\n```\n"} }, { "label": "setSymbol", "kind": 12, @@ -451,19 +451,19 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, string) => string", - "documentation": {"kind": "markdown", "value": "\n`joinUnsafe(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Under the hood this will run JavaScript's `toString` on all the array items.\n\nSee [Array.join](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join)\n\n## Examples\n```rescript\nlet array = [1, 2, 3]\n\nConsole.log(array->Array.joinUnsafe(\" -- \")) // 1 -- 2 -- 3\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`joinUnsafe(array, separator)` produces a string where all items of `array` are printed, separated by `separator`. Under the hood this will run JavaScript's `toString` on all the array items.\n\nSee [Array.join](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join)\n\n## Examples\n\n```rescript\n[1, 2, 3]\n->Array.joinUnsafe(\" -- \")\n->assertEqual(\"1 -- 2 -- 3\")\n```\n"} }, { "label": "mapWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => 'b) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`mapWithIndex(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray =\n array->Array.mapWithIndex((greeting, index) =>\n greeting ++ \" at position \" ++ Int.toString(index)\n )\n\nConsole.log(mappedArray) // [\"Hello at position 0\", \"Hi at position 1\", \"Good bye at position 2\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`mapWithIndex(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray =\n array->Array.mapWithIndex((greeting, index) =>\n greeting ++ \" at position \" ++ Int.toString(index)\n )\n\nassertEqual(mappedArray, [\"Hello at position 0\", \"Hi at position 1\", \"Good bye at position 2\"])\n```\n"} }, { "label": "flatMapWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => array<'b>) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`flatMapWithIndex(array, mapper)` returns a new array concatenating the arrays returned from running `mapper` on all items in `array`.\n\n## Examples\n```rescript\ntype language = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\nConsole.log(\n array->Array.flatMapWithIndex((item, index) =>\n switch item {\n | ReScript => [index]\n | TypeScript => [index, index + 1]\n | JavaScript => [index, index + 1, index + 2]\n }\n ),\n)\n// [0, 1, 2, 2, 3, 4]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`flatMapWithIndex(array, mapper)` returns a new array concatenating the arrays returned from running `mapper` on all items in `array`.\n\n## Examples\n\n```rescript\ntype language = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\n\narray\n->Array.flatMapWithIndex((item, index) =>\n switch item {\n | ReScript => [index]\n | TypeScript => [index, index + 1]\n | JavaScript => [index, index + 1, index + 2]\n }\n)\n->assertEqual([0, 1, 2, 2, 3, 4])\n```\n"} }, { "label": "copyWithinToEnd", "kind": 12, @@ -475,43 +475,43 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, 'a) => unit", - "documentation": {"kind": "markdown", "value": "\n`unshift(array, item)` inserts a new item at the start of the array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.unshift(\"yay\")\n\nConsole.log(someArray) // [\"yay\", \"hi\", \"hello\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`unshift(array, item)` inserts a new item at the start of the array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.unshift`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.unshift(\"yay\")\nsomeArray->assertEqual([\"yay\", \"hi\", \"hello\"])\n```\n"} }, { "label": "indexOf", "kind": 12, "tags": [], "detail": "(array<'a>, 'a) => int", - "documentation": {"kind": "markdown", "value": "\n`indexOf(array, item)` returns the index of the provided `item` in `array`. Uses [strict check for equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) when comparing items.\n\nReturns `-1` if the item doesn not exist. Check out `Array.indexOfOpt` for a version that returns `None` instead of `-1` if the item does not exist.\n\nSee [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) on MDN.\n\n## Examples\n```rescript\nConsole.log([1, 2]->Array.indexOf(2)) // 1\nConsole.log([1, 2]->Array.indexOf(3)) // -1\nConsole.log([{\"language\": \"ReScript\"}]->Array.indexOf({\"language\": \"ReScript\"})) // -1, because of strict equality\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`indexOf(array, item)` returns the index of the provided `item` in `array`. Uses [strict check for equality](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Strict_equality) when comparing items.\n\nReturns `-1` if the item doesn not exist. Check out `Array.indexOfOpt` for a version that returns `None` instead of `-1` if the item does not exist.\n\nSee [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) on MDN.\n\n## Examples\n\n```rescript\n[1, 2]->Array.indexOf(2)->assertEqual(1)\n[1, 2]->Array.indexOf(3)->assertEqual(-1)\n\n[{\"language\": \"ReScript\"}]\n->Array.indexOf({\"language\": \"ReScript\"})\n->assertEqual(-1) // -1, because of strict equality\n```\n"} }, { "label": "push", "kind": 12, "tags": [], "detail": "(array<'a>, 'a) => unit", - "documentation": {"kind": "markdown", "value": "\n`push(array, item)` appends `item` to the end of `array`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.push(\"yay\")\n\nConsole.log(someArray) // [\"hi\", \"hello\", \"yay\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`push(array, item)` appends `item` to the end of `array`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\n\nsomeArray->Array.push(\"yay\")\n\nsomeArray->assertEqual([\"hi\", \"hello\", \"yay\"])\n```\n"} }, { "label": "toSorted", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, 'a) => Ordering.t) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`toSorted(array, comparator)` returns a new, sorted array from `array`, using the `comparator` function.\n\nSee [`Array.toSorted`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted) on MDN.\n\n## Examples\n```rescript\nlet someArray = [3, 2, 1]\nlet sorted = someArray->Array.toSorted(Int.compare)\n\nConsole.log(sorted) // [1, 2, 3]\nConsole.log(someArray) // [3, 2, 1]. Original unchanged\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`toSorted(array, comparator)` returns a new, sorted array from `array`, using the `comparator` function.\n\nSee [`Array.toSorted`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [3, 2, 1]\n\nsomeArray\n->Array.toSorted(Int.compare)\n->assertEqual([1, 2, 3])\n\nsomeArray->assertEqual([3, 2, 1]) // Original unchanged\n```\n"} }, { "label": "reduceWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, 'b, ('b, 'a, int) => 'b) => 'b", - "documentation": {"kind": "markdown", "value": "\n `reduceWithIndex(x, init, fn)`\n\n Applies `fn` to each element of `xs` from beginning to end. Function `fn` has three parameters: the item from the array and an “accumulator”, which starts with a value of `init` and the index of each element. `reduceWithIndex` returns the final value of the accumulator.\n\n ```res example\n Array.reduceWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i) == 16\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`reduceWithIndex(x, init, fn)`\n\nApplies `fn` to each element of `xs` from beginning to end. Function `fn` has three parameters: the item from the array and an “accumulator”, which starts with a value of `init` and the index of each element. `reduceWithIndex` returns the final value of the accumulator.\n\n## Examples\n\n```rescript\nArray.reduceWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i)->assertEqual(16)\n\nArray.reduceWithIndex([1, 2, 3], list{}, (acc, v, i) => list{v + i, ...acc})->assertEqual(list{5, 3, 1})\n\nArray.reduceWithIndex([], list{}, (acc, v, i) => list{v + i, ...acc})->assertEqual(list{})\n```\n"} }, { "label": "some", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => bool) => bool", - "documentation": {"kind": "markdown", "value": "\n`some(array, predicate)` returns true if `predicate` returns true for any element in `array`.\n\nSee [`Array.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\nConsole.log(array->Array.some(greeting => greeting === \"Hello\")) // true\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`some(array, predicate)` returns true if `predicate` returns true for any element in `array`.\n\nSee [`Array.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray\n->Array.some(greeting => greeting === \"Hello\")\n->assertEqual(true)\n```\n"} }, { "label": "unsafe_get", "kind": 12, "tags": [1], "detail": "(array<'a>, int) => 'a", - "documentation": {"kind": "markdown", "value": "Deprecated: Use getUnsafe instead. This will be removed in v13\n\n\n`unsafe_get(array, index)` returns the element at `index` of `array`.\n\nThis is _unsafe_, meaning it will return `undefined` value if `index` does not exist in `array`.\n\nUse `Array.unsafe_get` only when you are sure the `index` exists (i.e. when using for-loop).\n\n## Examples\n```rescript\nlet array = [1, 2, 3]\nfor index in 0 to array->Array.length - 1 {\n let value = array->Array.unsafe_get(index)\n Console.log(value)\n}\n```\n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use getUnsafe instead. This will be removed in v13\n\n\n`unsafe_get(array, index)` returns the element at `index` of `array`.\n\nThis is _unsafe_, meaning it will return `undefined` value if `index` does not exist in `array`.\n\nUse `Array.unsafe_get` only when you are sure the `index` exists (i.e. when using for-loop).\n\n## Examples\n\n```rescript\nlet array = [1, 2, 3]\nfor index in 0 to array->Array.length - 1 {\n let value = array->Array.unsafe_get(index)\n Console.log(value)\n}\n```\n"} }, { "label": "copyAllWithin", "kind": 12, @@ -523,37 +523,37 @@ Path Array. "kind": 12, "tags": [], "detail": "array> => array<'a>", - "documentation": {"kind": "markdown", "value": "\n `keepSome(arr)`\n\n Returns a new array containing `value` for all elements that are `Some(value)`\n and ignoring every value that is `None`\n\n ```res example\n Array.keepSome([Some(1), None, Some(3)]) == [1, 3]\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`keepSome(arr)`\n\nReturns a new array containing `value` for all elements that are `Some(value)`\nand ignoring every value that is `None`\n\n## Examples\n\n```rescript\nArray.keepSome([Some(1), None, Some(3)])->assertEqual([1, 3])\n\nArray.keepSome([Some(1), Some(2), Some(3)])->assertEqual([1, 2, 3])\n\nArray.keepSome([None, None, None])->assertEqual([])\n\nArray.keepSome([])->assertEqual([])\n```\n"} }, { "label": "at", "kind": 12, "tags": [], "detail": "(array<'a>, int) => option<'a>", - "documentation": {"kind": "markdown", "value": "\n `at(array, index)`\n\n Get an element by its index. Negative indices count backwards from the last item.\n\n ## Examples\n ```rescript\n [\"a\", \"b\", \"c\"]->Array.at(0) // Some(\"a\")\n [\"a\", \"b\", \"c\"]->Array.at(2) // Some(\"c\")\n [\"a\", \"b\", \"c\"]->Array.at(3) // None\n [\"a\", \"b\", \"c\"]->Array.at(-1) // Some(\"c\")\n [\"a\", \"b\", \"c\"]->Array.at(-3) // Some(\"a\")\n [\"a\", \"b\", \"c\"]->Array.at(-4) // None\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`at(array, index)`\n\nGet an element by its index. Negative indices count backwards from the last item.\n\n## Examples\n\n```rescript\n[\"a\", \"b\", \"c\"]->Array.at(0)->assertEqual(Some(\"a\"))\n[\"a\", \"b\", \"c\"]->Array.at(2)->assertEqual(Some(\"c\"))\n[\"a\", \"b\", \"c\"]->Array.at(3)->assertEqual(None)\n[\"a\", \"b\", \"c\"]->Array.at(-1)->assertEqual(Some(\"c\"))\n[\"a\", \"b\", \"c\"]->Array.at(-3)->assertEqual(Some(\"a\"))\n[\"a\", \"b\", \"c\"]->Array.at(-4)->assertEqual(None)\n```\n"} }, { "label": "pop", "kind": 12, "tags": [], "detail": "array<'a> => option<'a>", - "documentation": {"kind": "markdown", "value": "\n`pop(array)` removes the last item from `array` and returns it.\n\nBeware this will *mutate* the array.\n\nSee [`Array.pop`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nlet lastItem = someArray->Array.pop // \"hello\"\n\nConsole.log(someArray) // [\"hi\"]. Notice last item is gone.\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`pop(array)` removes the last item from `array` and returns it.\n\nBeware this will *mutate* the array.\n\nSee [`Array.pop`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\n\nsomeArray\n->Array.pop\n->assertEqual(Some(\"hello\"))\n\nsomeArray->assertEqual([\"hi\"]) // Notice last item is gone.\n```\n"} }, { "label": "get", "kind": 12, "tags": [], "detail": "(array<'a>, int) => option<'a>", - "documentation": {"kind": "markdown", "value": "\n`get(array, index)` returns the element at `index` of `array`.\n\nReturns `None` if the index does not exist in the array. Equivalent to doing `array[index]` in JavaScript.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray->Array.get(0) == Some(\"Hello\") // true\narray->Array.get(3) == None // true\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`get(array, index)` returns the element at `index` of `array`.\n\nReturns `None` if the index does not exist in the array. Equivalent to doing `array[index]` in JavaScript.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\n\narray\n->Array.get(0)\n->assertEqual(Some(\"Hello\"))\n\narray\n->Array.get(3)\n->assertEqual(None)\n```\n"} }, { "label": "pushMany", "kind": 12, "tags": [], "detail": "(array<'a>, array<'a>) => unit", - "documentation": {"kind": "markdown", "value": "\n`pushMany(array, itemsArray)` appends many new items to the end of the array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN.\n\n## Examples\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.pushMany([\"yay\", \"wehoo\"])\n\nConsole.log(someArray) // [\"hi\", \"hello\", \"yay\", \"wehoo\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`pushMany(array, itemsArray)` appends many new items to the end of the array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\n\nsomeArray->Array.pushMany([\"yay\", \"wehoo\"])\nsomeArray->assertEqual([\"hi\", \"hello\", \"yay\", \"wehoo\"])\n```\n"} }, { "label": "fromIterator", "kind": 12, "tags": [], "detail": "Iterator.t<'a> => array<'a>", - "documentation": {"kind": "markdown", "value": "\n `fromIterator(iterator)`\n\n Creates an array from the provided `iterator`\n\n ```res example\n let map = Map.fromArray([(\"foo\", 1), (\"bar\", 2)])\n\n Array.fromIterator(map->Map.values) // [1, 2]\n ```\n "} + "documentation": {"kind": "markdown", "value": "\n`fromIterator(iterator)`\n\nCreates an array from the provided `iterator`\n\n## Examples\n\n```rescript\nMap.fromArray([(\"foo\", 1), (\"bar\", 2)])\n->Map.values\n->Array.fromIterator\n->assertEqual([1, 2])\n```\n"} }, { "label": "forEach", "kind": 12, @@ -565,7 +565,7 @@ Path Array. "kind": 12, "tags": [], "detail": "(array<'a>, 'a => array<'b>) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`flatMap(array, mapper)` returns a new array concatenating the arrays returned from running `mapper` on all items in `array`.\n\n## Examples\n```rescript\ntype language = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\nConsole.log(\n array->Array.flatMap(item =>\n switch item {\n | ReScript => [1, 2, 3]\n | TypeScript => [4, 5, 6]\n | JavaScript => [7, 8, 9]\n }\n ),\n)\n// [1, 2, 3, 4, 5, 6, 7, 8, 9]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`flatMap(array, mapper)` returns a new array concatenating the arrays returned from running `mapper` on all items in `array`.\n\n## Examples\n\n```rescript\ntype language = ReScript | TypeScript | JavaScript\n\nlet array = [ReScript, TypeScript, JavaScript]\n\narray\n->Array.flatMap(item =>\n switch item {\n | ReScript => [1, 2, 3]\n | TypeScript => [4, 5, 6]\n | JavaScript => [7, 8, 9]\n }\n)\n->assertEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])\n```\n"} }, { "label": "fromArrayLike", "kind": 12, @@ -592,19 +592,19 @@ Path Array.m "kind": 12, "tags": [], "detail": "(~length: int, 'a) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n `make(~length, init)`\n\n Creates an array of length `length` initialized with the value of `init`.\n\n ```res example\n Array.make(~length=3, #apple) == [#apple, #apple, #apple]\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n`make(~length, init)`\n\nCreates an array of length `length` initialized with the value of `init`.\n\n## Examples\n\n```rescript\nArray.make(~length=3, #apple)->assertEqual([#apple, #apple, #apple])\nArray.make(~length=6, 7)->assertEqual([7, 7, 7, 7, 7, 7])\n```\n"} }, { "label": "map", "kind": 12, "tags": [], "detail": "(array<'a>, 'a => 'b) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`map(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray = array->Array.map(greeting => greeting ++ \" to you\")\n\nConsole.log(mappedArray) // [\"Hello to you\", \"Hi to you\", \"Good bye to you\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`map(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray = array->Array.map(greeting => greeting ++ \" to you\")\n\nassertEqual(mappedArray, [\"Hello to you\", \"Hi to you\", \"Good bye to you\"])\n```\n"} }, { "label": "mapWithIndex", "kind": 12, "tags": [], "detail": "(array<'a>, ('a, int) => 'b) => array<'b>", - "documentation": {"kind": "markdown", "value": "\n`mapWithIndex(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray =\n array->Array.mapWithIndex((greeting, index) =>\n greeting ++ \" at position \" ++ Int.toString(index)\n )\n\nConsole.log(mappedArray) // [\"Hello at position 0\", \"Hi at position 1\", \"Good bye at position 2\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`mapWithIndex(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray =\n array->Array.mapWithIndex((greeting, index) =>\n greeting ++ \" at position \" ++ Int.toString(index)\n )\n\nassertEqual(mappedArray, [\"Hello at position 0\", \"Hi at position 1\", \"Good bye at position 2\"])\n```\n"} }] Complete src/Completion.res 15:17 @@ -2348,13 +2348,13 @@ Path Belt.Int.t "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }, { "label": "Belt.Int.toFloat", "kind": 12, "tags": [], "detail": "int => float", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toFloat(1) === 1.0) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nBelt.Int.toFloat(1)->assertEqual(1.0)\n```\n"} }] Complete src/Completion.res 423:19 @@ -2397,7 +2397,7 @@ Path Belt.Result.g "kind": 12, "tags": [], "detail": "t<'a, 'b> => 'a", - "documentation": {"kind": "markdown", "value": "\n`getExn(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception\n\n## Examples\n\n```rescript\nBelt.Result.getExn(Belt.Result.Ok(42)) == 42\n\nBelt.Result.getExn(Belt.Result.Error(\"Invalid data\")) /* raises exception */\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`getExn(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception\n\n## Examples\n\n```rescript\nBelt.Result.Ok(42)\n->Belt.Result.getExn\n->assertEqual(42)\n\n\nswitch Belt.Result.getExn(Belt.Result.Error(\"Invalid data\")) { // raise a exception\n| exception _ => assert(true)\n| _ => assert(false)\n}\n```\n"} }, { "label": "Belt.Result.getWithDefault", "kind": 12, @@ -2481,7 +2481,7 @@ Path Belt.Int.toS "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }] Complete src/Completion.res 463:30 diff --git a/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt b/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt index eea7ad9297..c00015c1b5 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt @@ -15,13 +15,13 @@ Path Belt.Int.f "kind": 12, "tags": [], "detail": "string => option", - "documentation": {"kind": "markdown", "value": "\nConverts a given `string` to an `int`. Returns `Some(int)` when the input is a number, `None` otherwise.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.fromString(\"1\") === Some(1)) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `string` to an `int`. Returns `Some(int)` when the input is a number, `None` otherwise.\n\n## Examples\n\n```rescript\nBelt.Int.fromString(\"1\")->assertEqual(Some(1))\n```\n"} }, { "label": "Belt.Int.fromFloat", "kind": 12, "tags": [], "detail": "float => int", - "documentation": {"kind": "markdown", "value": "\nConverts a given `float` to an `int`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.fromFloat(1.0) === 1) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `float` to an `int`.\n\n## Examples\n\n```rescript\nBelt.Int.fromFloat(1.0)->assertEqual(1)\n```\n"} }] Complete src/CompletionInferValues.res 18:30 @@ -238,13 +238,13 @@ Path Belt.Int.t "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }, { "label": "Belt.Int.toFloat", "kind": 12, "tags": [], "detail": "int => float", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toFloat(1) === 1.0) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nBelt.Int.toFloat(1)->assertEqual(1.0)\n```\n"} }] Complete src/CompletionInferValues.res 50:108 @@ -465,7 +465,7 @@ Path Belt.Int.toS "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }] Complete src/CompletionInferValues.res 98:109 @@ -490,7 +490,7 @@ Path Belt.Int.toS "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }] Complete src/CompletionInferValues.res 102:102 @@ -516,7 +516,7 @@ Path Belt.Int.toS "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }] Complete src/CompletionInferValues.res 106:88 @@ -648,7 +648,7 @@ Path Belt.Int.toSt "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }] Complete src/CompletionInferValues.res 130:26 diff --git a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt index 6036538868..14bfad209b 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt @@ -225,49 +225,49 @@ Path Belt.Int. "kind": 12, "tags": [], "detail": "string => option", - "documentation": {"kind": "markdown", "value": "\nConverts a given `string` to an `int`. Returns `Some(int)` when the input is a number, `None` otherwise.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.fromString(\"1\") === Some(1)) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `string` to an `int`. Returns `Some(int)` when the input is a number, `None` otherwise.\n\n## Examples\n\n```rescript\nBelt.Int.fromString(\"1\")->assertEqual(Some(1))\n```\n"} }, { "label": "Belt.Int.*", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nMultiplication of two `int` values. Same as the multiplication from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(2 * 2 === 4) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nMultiplication of two `int` values. Same as the multiplication from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(2 * 2, 4)\n```\n"} }, { "label": "Belt.Int./", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nDivision of two `int` values. Same as the division from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(4 / 2 === 2); /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nDivision of two `int` values. Same as the division from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(4 / 2, 2)\n```\n"} }, { "label": "Belt.Int.toString", "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }, { "label": "Belt.Int.toFloat", "kind": 12, "tags": [], "detail": "int => float", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toFloat(1) === 1.0) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nBelt.Int.toFloat(1)->assertEqual(1.0)\n```\n"} }, { "label": "Belt.Int.fromFloat", "kind": 12, "tags": [], "detail": "float => int", - "documentation": {"kind": "markdown", "value": "\nConverts a given `float` to an `int`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.fromFloat(1.0) === 1) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `float` to an `int`.\n\n## Examples\n\n```rescript\nBelt.Int.fromFloat(1.0)->assertEqual(1)\n```\n"} }, { "label": "Belt.Int.-", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nSubtraction of two `int` values. Same as the subtraction from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(2 - 1 === 1) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nSubtraction of two `int` values. Same as the subtraction from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(2 - 1, 1)\n```\n"} }, { "label": "Belt.Int.+", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nAddition of two `int` values. Same as the addition from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(2 + 2 === 4) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nAddition of two `int` values. Same as the addition from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(2 + 2, 4)\n```\n"} }] Complete src/CompletionJsx.res 26:14 @@ -304,49 +304,49 @@ Path Belt.Int. "kind": 12, "tags": [], "detail": "string => option", - "documentation": {"kind": "markdown", "value": "\nConverts a given `string` to an `int`. Returns `Some(int)` when the input is a number, `None` otherwise.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.fromString(\"1\") === Some(1)) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `string` to an `int`. Returns `Some(int)` when the input is a number, `None` otherwise.\n\n## Examples\n\n```rescript\nBelt.Int.fromString(\"1\")->assertEqual(Some(1))\n```\n"} }, { "label": "Belt.Int.*", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nMultiplication of two `int` values. Same as the multiplication from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(2 * 2 === 4) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nMultiplication of two `int` values. Same as the multiplication from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(2 * 2, 4)\n```\n"} }, { "label": "Belt.Int./", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nDivision of two `int` values. Same as the division from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(4 / 2 === 2); /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nDivision of two `int` values. Same as the division from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(4 / 2, 2)\n```\n"} }, { "label": "Belt.Int.toString", "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }, { "label": "Belt.Int.toFloat", "kind": 12, "tags": [], "detail": "int => float", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toFloat(1) === 1.0) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nBelt.Int.toFloat(1)->assertEqual(1.0)\n```\n"} }, { "label": "Belt.Int.fromFloat", "kind": 12, "tags": [], "detail": "float => int", - "documentation": {"kind": "markdown", "value": "\nConverts a given `float` to an `int`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.fromFloat(1.0) === 1) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `float` to an `int`.\n\n## Examples\n\n```rescript\nBelt.Int.fromFloat(1.0)->assertEqual(1)\n```\n"} }, { "label": "Belt.Int.-", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nSubtraction of two `int` values. Same as the subtraction from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(2 - 1 === 1) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nSubtraction of two `int` values. Same as the subtraction from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(2 - 1, 1)\n```\n"} }, { "label": "Belt.Int.+", "kind": 12, "tags": [], "detail": "(int, int) => int", - "documentation": {"kind": "markdown", "value": "\nAddition of two `int` values. Same as the addition from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nJs.log(2 + 2 === 4) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nAddition of two `int` values. Same as the addition from `Pervasives`.\n\n## Examples\n\n```rescript\nopen Belt.Int\nassertEqual(2 + 2, 4)\n```\n"} }] Complete src/CompletionJsx.res 28:20 diff --git a/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt b/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt index ab4a1661d6..aff905d82f 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt @@ -351,13 +351,13 @@ Path Belt.Int.t "kind": 12, "tags": [], "detail": "int => string", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toString(1) === \"1\") /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `string`. Uses the JavaScript `String` constructor under the hood.\n\n## Examples\n\n```rescript\nBelt.Int.toString(1)->assertEqual(\"1\")\n```\n"} }, { "label": "Belt.Int.toFloat", "kind": 12, "tags": [], "detail": "int => float", - "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nJs.log(Belt.Int.toFloat(1) === 1.0) /* true */\n```\n"} + "documentation": {"kind": "markdown", "value": "\nConverts a given `int` to a `float`.\n\n## Examples\n\n```rescript\nBelt.Int.toFloat(1)->assertEqual(1.0)\n```\n"} }] Complete src/CompletionPipeChain.res 70:12 diff --git a/tests/analysis_tests/tests/src/expected/SignatureHelp.res.txt b/tests/analysis_tests/tests/src/expected/SignatureHelp.res.txt index 1d86e2147d..3c546a4318 100644 --- a/tests/analysis_tests/tests/src/expected/SignatureHelp.res.txt +++ b/tests/analysis_tests/tests/src/expected/SignatureHelp.res.txt @@ -461,7 +461,7 @@ extracted params: "signatures": [{ "label": "(array, int => int) => array", "parameters": [{"label": [0, 11], "documentation": {"kind": "markdown", "value": ""}}, {"label": [13, 23], "documentation": {"kind": "markdown", "value": ""}}], - "documentation": {"kind": "markdown", "value": "\n`map(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray = array->Array.map(greeting => greeting ++ \" to you\")\n\nConsole.log(mappedArray) // [\"Hello to you\", \"Hi to you\", \"Good bye to you\"]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`map(array, fn)` returns a new array with all elements from `array`, each element transformed using the provided `fn`.\n\nSee [`Array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on MDN.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\nlet mappedArray = array->Array.map(greeting => greeting ++ \" to you\")\n\nassertEqual(mappedArray, [\"Hello to you\", \"Hi to you\", \"Good bye to you\"])\n```\n"} }], "activeSignature": 0, "activeParameter": 1 diff --git a/tests/docstrings_examples/DocTest.res b/tests/docstrings_examples/DocTest.res new file mode 100644 index 0000000000..afd7f74c67 --- /dev/null +++ b/tests/docstrings_examples/DocTest.res @@ -0,0 +1,545 @@ +module Node = { + module Path = { + @module("path") external join2: (string, string) => string = "join" + @module("path") @variadic external join: array => string = "join" + } + + module Process = { + @scope("process") external exit: int => unit = "exit" + @scope(("process", "stderr")) + external stderrWrite: string => unit = "write" + @scope("process") external cwd: unit => string = "cwd" + @val @scope("process") + external argv: array = "argv" + } + + module Fs = { + @module("fs") external existsSync: string => bool = "existsSync" + @module("fs") external readdirSync: string => array = "readdirSync" + @module("node:fs/promises") external writeFile: (string, string) => promise = "writeFile" + } + + module Buffer = { + type t + @send external toString: t => string = "toString" + } + + module ChildProcess = { + type spawnSyncReturns = {stdout: Buffer.t} + @module("child_process") + external spawnSync: (string, array) => spawnSyncReturns = "spawnSync" + + type readable + type spawnReturns = {stderr: readable, stdout: readable} + type options = {cwd?: string, env?: Dict.t, timeout?: int} + @module("child_process") + external spawn: (string, array, ~options: options=?) => spawnReturns = "spawn" + + @send external on: (readable, string, Buffer.t => unit) => unit = "on" + @send external onFromSpawn: (spawnReturns, string, Js.Null.t => unit) => unit = "on" + @send + external once: (spawnReturns, string, (Js.Null.t, Js.Null.t) => unit) => unit = + "once" + @send + external onceError: (spawnReturns, string, Js.Exn.t => unit) => unit = "once" + } + + module OS = { + @module("os") + external tmpdir: unit => string = "tmpdir" + + @module("os") + external cpus: unit => array<{.}> = "cpus" + } + + module Util = { + type arg = {@as("type") type_: string} + type config = { + args: array, + options: Dict.t, + } + type parsed = { + values: Dict.t, + positionals: array, + } + @module("node:util") external parseArgs: config => parsed = "parseArgs" + } +} + +open Node + +module Docgen = RescriptTools.Docgen + +let bscBin = Path.join(["cli", "bsc"]) + +let options = Dict.fromArray([("ignore-runtime-tests", {Util.type_: "string"})]) + +let {Util.values: values} = Util.parseArgs({ + args: Process.argv->Array.sliceToEnd(~start=2), + options, +}) + +let ignoreRuntimeTests = switch values->Dict.get("ignore-runtime-tests") { +| Some(v) => + v + ->String.split(",") + ->Array.map(s => s->String.trim) +| None => [] +} + +module SpawnAsync = { + type t = { + stdout: array, + stderr: array, + code: Null.t, + } + let run = async (~command, ~args, ~options=?) => { + let spawn = ChildProcess.spawn(command, args, ~options?) + let stdout = [] + let stderr = [] + spawn.stdout->ChildProcess.on("data", data => { + Array.push(stdout, data) + }) + spawn.stderr->ChildProcess.on("data", data => { + Array.push(stderr, data) + }) + await Promise.make((resolve, reject) => { + spawn->ChildProcess.once("error", (_, _) => { + reject({stdout, stderr, code: Null.make(1.0)}) + }) + spawn->ChildProcess.once("close", (code, _signal) => { + resolve({stdout, stderr, code}) + }) + }) + } +} + +type example = { + id: string, + kind: string, + name: string, + docstrings: array, +} + +let createFileInTempDir = id => Path.join2(OS.tmpdir(), id) + +let compileTest = async (~id as _, ~code) => { + let {stderr, stdout} = await SpawnAsync.run( + ~command=bscBin, + // NOTE: warnings argument (-w) should be before eval (-e) argument + ~args=["-w", "-3-109-44", "-e", code], + ) + + switch Array.length(stderr) > 0 { + | true => + stderr + ->Array.map(e => e->Buffer.toString) + ->Array.join("") + ->Error + | false => + stdout + ->Array.map(e => e->Buffer.toString) + ->Array.join("") + ->Ok + } +} + +let runtimeTests = async code => { + let {stdout, stderr, code: exitCode} = await SpawnAsync.run( + ~command="node", + ~args=["-e", code, "--input-type", "commonjs"], + ~options={ + cwd: Process.cwd(), + timeout: 2000, + }, + ) + + // Some expressions, like, `console.error("error")` is printed to stderr but + // exit code is 0 + let std = switch exitCode->Null.toOption { + | Some(exitCode) if exitCode == 0.0 && Array.length(stderr) > 0 => stderr->Ok + | Some(exitCode) if exitCode == 0.0 => stdout->Ok + | None | Some(_) => Error(Array.length(stderr) > 0 ? stderr : stdout) + } + + switch std { + | Ok(buf) => + buf + ->Array.map(e => e->Buffer.toString) + ->Array.join("") + ->Ok + | Error(buf) => + buf + ->Array.map(e => e->Buffer.toString) + ->Array.join("") + ->Error + } +} + +let indentOutputCode = code => { + let indent = String.repeat(" ", 2) + + code + ->String.split("\n") + ->Array.map(s => `${indent}${s}`) + ->Array.join("\n") +} + +type error = + | ReScriptError(string) + | RuntimeError({rescript: string, js: string, error: string}) + +let extractDocFromFile = file => { + let toolsBin = Path.join([Process.cwd(), "cli", "rescript-tools"]) + let spawn = ChildProcess.spawnSync(toolsBin, ["doc", file]) + + let output = spawn.stdout->Buffer.toString + + try { + output + ->JSON.parseExn + ->Docgen.decodeFromJson + } catch { + | Exn.Error(_) => Error.panic(`Failed to generate docstrings from ${file}`) + | _ => assert(false) + } +} + +let getExamples = ({items}: Docgen.doc) => { + let rec loop = (items: list, acc: list) => { + switch items { + | list{Value({docstrings, id, name}), ...rest} => + loop(rest, list{{id, name, docstrings, kind: "value"}, ...acc}) + | list{Type({docstrings, id, name}), ...rest} => + loop(rest, list{{id, name, docstrings, kind: "type"}, ...acc}) + | list{Module({id, name, docstrings, items}), ...rest} => + loop( + list{...rest, ...List.fromArray(items)}, + list{{id, name, docstrings, kind: "module"}, ...acc}, + ) + | list{ModuleType({id, name, docstrings, items}), ...rest} => + loop( + list{...rest, ...List.fromArray(items)}, + list{{id, name, docstrings, kind: "moduleType"}, ...acc}, + ) + | list{ModuleAlias({id, name, docstrings, items}), ...rest} => + loop( + list{...rest, ...List.fromArray(items)}, + list{{id, name, docstrings, kind: "moduleAlias"}, ...acc}, + ) + | list{} => acc + } + } + + items + ->List.fromArray + ->loop(list{}) + ->List.toArray + ->Array.filter(({docstrings}) => Array.length(docstrings) > 0) +} + +let getCodeBlocks = example => { + let rec loopEndCodeBlock = (lines, acc) => { + switch lines { + | list{hd, ...rest} => + if ( + hd + ->String.trim + ->String.endsWith("```") + ) { + acc + } else { + loopEndCodeBlock(rest, list{hd, ...acc}) + } + | list{} => panic(`Failed to find end of code block for ${example.kind}: ${example.id}`) + } + } + + let rec loop = (lines: list, acc: list) => { + switch lines { + | list{hd, ...rest} => + switch hd + ->String.trim + ->String.startsWith("```res") { + | true => + let code = loopEndCodeBlock(rest, list{}) + loop( + rest, + list{ + code + ->List.reverse + ->List.toArray + ->Array.join("\n"), + ...acc, + }, + ) + | false => loop(rest, acc) + } + | list{} => acc + } + } + + example.docstrings + ->Array.reduce([], (acc, docstring) => acc->Array.concat(docstring->String.split("\n"))) + ->List.fromArray + ->loop(list{}) + ->List.toArray + ->Belt.Array.reverse + ->Array.join("\n\n") +} + +let chunkArray = (array, chunkSize) => { + let result = [] + + let rec loop = (i: int) => { + if i < Array.length(array) { + Array.push( + result, + Array.slice(array, ~start=i, ~end=Math.Int.min(i + chunkSize, Array.length(array))), + ) + loop(i + chunkSize) + } + } + + loop(0) + result +} + +let main = async () => { + let files = Fs.readdirSync("runtime") + + let modules = + files + // Ignore Js modules and RescriptTools for now + ->Array.filter(f => !String.startsWith(f, "Js") && !String.startsWith(f, "RescriptTools")) + ->Array.filter(f => f->String.endsWith(".res") || f->String.endsWith(".resi")) + // ->Array.filter(f => f === "Uint8ClampedArray.res") + ->Array.reduce([], (acc, cur) => { + let isInterface = cur->String.endsWith(".resi") + + let resi = Path.join2("runtime", cur ++ "i") + + // If .resi files exists append to array + if !isInterface && Fs.existsSync(resi) { + Array.concat(acc, [cur ++ "i"]) + } else if !Array.includes(acc, cur) { + Array.concat(acc, [cur]) + } else { + acc + } + }) + ->Array.map(f => extractDocFromFile(Path.join(["runtime", f]))->getExamples) + ->Array.flat + + let batchSize = OS.cpus()->Array.length * 2 + + // Console.log2("module length", modules->Array.length) + let chuncks = modules->chunkArray(batchSize) + + Console.log2("chuncks length", chuncks->Array.length) + Console.log2("chunck part size", chuncks->Array.reduce(0, (acc, cur) => acc + Array.length(cur))) + + let context = ref(0) + + let asyncIterator = AsyncIterator.make(async () => { + let currentValue = context.contents + // Increment current value + context := currentValue + 1 + + { + AsyncIterator.value: Some(currentValue), + done: currentValue == Array.length(chuncks) - 1, + } + }) + + let result = [] + // await asyncIterator->AsyncIterator.forEach(async value => + // switch value { + // | Some(value) => + // let c = Array.getUnsafe(chuncks, value) + // + // let a = await c->Array.map(async example => { + // let id = example.id->String.replaceAll(".", "__") + // let rescriptCode = example->getCodeBlocks + // let jsCode = await compileTest(~id, ~code=rescriptCode) + // (example, (rescriptCode, jsCode)) + // })->Promise.all + // + // Array.push(result, a)->ignore + // + // | None => () + // } + // ) + + let processMyAsyncIterator = async () => { + // ReScript doesn't have `for ... of` loops, but it's easy to mimic using a while loop. + let break = ref(false) + + while !break.contents { + // Await the next iterator value + let {value, done} = await asyncIterator->AsyncIterator.next + + // Exit the while loop if the iterator says it's done + break := done + + // This will log the (int) value of the current async iteration, if a value was returned. + switch value { + | Some(index) => + let c = Array.getUnsafe(chuncks, index) + let a = + await c + ->Array.map(async example => { + let id = example.id->String.replaceAll(".", "__") + let rescriptCode = example->getCodeBlocks + let jsCode = await compileTest(~id, ~code=rescriptCode) + (example, (rescriptCode, jsCode)) + }) + ->Promise.all + + Array.push(result, a) + + | None => () + } + } + } + + let () = await processMyAsyncIterator() + + Console.log("Compiation tests finished") + + let compilationResults = result->Array.flat + + // let compilationResults = + // (await chuncks + // ->Array.map(async arrExample => { + // await arrExample + // ->Array.map(async example => { + // let id = example.id->String.replaceAll(".", "__") + // let rescriptCode = example->getCodeBlocks + // let jsCode = await compileTest(~id, ~code=rescriptCode) + // (example, (rescriptCode, jsCode)) + // }) + // ->Promise.all + // }) + // ->Promise.all) + // ->Array.flat + + // let compilationResults = + // await modules + // ->Array.map(async example => { + // let id = example.id->String.replaceAll(".", "__") + // let rescriptCode = example->getCodeBlocks + // let jsCode = await compileTest(~id, ~code=rescriptCode) + // (example, (rescriptCode, jsCode)) + // }) + // ->Promise.all + + let (compiled, compilationErrors) = compilationResults->Array.reduce(([], []), ( + acc, + (example, (rescriptCode, jsCode)), + ) => { + let (lhs, rhs) = acc + switch jsCode { + | Ok(jsCode) => lhs->Array.push((example, rescriptCode, jsCode)) + | Error(err) => rhs->Array.push((example, ReScriptError(err))) + } + (lhs, rhs) + }) + + let _batches = chunkArray(compiled, batchSize) + + // let a = + // await batches + // ->Array.map(async t => { + // (await t + // ->Array.filter((({id}, _, _)) => !Array.includes(ignoreRuntimeTests, id)) + // ->Array.map(async ((example, rescriptCode, jsCode)) => { + // let nodeTest = await runtimeTests(jsCode) + // switch nodeTest { + // | Ok(_) => None + // | Error(error) => Some(example, RuntimeError({rescript: rescriptCode, js: jsCode, error})) + // } + // }) + // ->Promise.all) + // ->Array.filterMap(i => + // switch i { + // | Some(i) => Some(i) + // | None => None + // } + // ) + // }) + // ->Promise.all + + let runtimeErrors = [] + // let runtimeErrors = Array.flat(a) + + // let runtimeErrors = + // (await compiled + // ->Array.filter((({id}, _, _)) => !Array.includes(ignoreRuntimeTests, id)) + // ->Array.map(async ((example, rescriptCode, jsCode)) => { + // let nodeTests = await jsCode->runtimeTests + // switch nodeTests { + // | Ok(_) => None + // | Error(error) => Some(example, RuntimeError({rescript: rescriptCode, js: jsCode, error})) + // } + // }) + // ->Promise.all) + // ->Array.filterMap(i => + // switch i { + // | Some(i) => Some(i) + // | None => None + // } + // ) + + let allErrors = Array.concat(runtimeErrors, compilationErrors) + + // Print Errors + let () = allErrors->Array.forEach(((example, errors)) => { + let red = s => `\x1B[1;31m${s}\x1B[0m` + let cyan = s => `\x1b[36m${s}\x1b[0m` + let kind = switch example.kind { + | "moduleAlias" => "module alias" + | other => other + } + + let a = switch errors { + | ReScriptError(error) => + let err = + error + ->String.split("\n") + // Drop line of filename + ->Array.filterWithIndex((_, i) => i !== 2) + ->Array.join("\n") + + `${"error"->red}: failed to compile examples from ${kind} ${example.id->cyan} +${err}` + | RuntimeError({rescript, js, error}) => + let indent = String.repeat(" ", 2) + + `${"runtime error"->red}: failed to run examples from ${kind} ${example.id->cyan} + +${indent}${"ReScript"->cyan} + +${rescript->indentOutputCode} + +${indent}${"Compiled Js"->cyan} + +${js->indentOutputCode} + +${indent}${"stacktrace"->red} + +${error->indentOutputCode} +` + } + + Process.stderrWrite(a) + }) + + let someError = allErrors->Array.length > 0 + + someError ? 1 : 0 +} + +let exitCode = await main() + +Process.exit(exitCode) diff --git a/tests/docstrings_examples/DocTest.res.mjs b/tests/docstrings_examples/DocTest.res.mjs new file mode 100644 index 0000000000..e00555fb8f --- /dev/null +++ b/tests/docstrings_examples/DocTest.res.mjs @@ -0,0 +1,495 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Fs from "fs"; +import * as Os from "os"; +import * as Exn from "rescript/lib/es6/Exn.js"; +import * as List from "rescript/lib/es6/List.js"; +import * as Path from "path"; +import * as $$Array from "rescript/lib/es6/Array.js"; +import * as $$Error from "rescript/lib/es6/Error.js"; +import * as Belt_List from "rescript/lib/es6/Belt_List.js"; +import * as Nodeutil from "node:util"; +import * as Belt_Array from "rescript/lib/es6/Belt_Array.js"; +import * as Pervasives from "rescript/lib/es6/Pervasives.js"; +import * as $$AsyncIterator from "rescript/lib/es6/AsyncIterator.js"; +import * as Child_process from "child_process"; +import * as Primitive_option from "rescript/lib/es6/Primitive_option.js"; +import * as Primitive_exceptions from "rescript/lib/es6/Primitive_exceptions.js"; +import * as RescriptTools_Docgen from "rescript/lib/es6/RescriptTools_Docgen.js"; + +let Path$1 = {}; + +let Process = {}; + +let Fs$1 = {}; + +let Buffer = {}; + +let ChildProcess = {}; + +let OS = {}; + +let Util = {}; + +let Node = { + Path: Path$1, + Process: Process, + Fs: Fs$1, + Buffer: Buffer, + ChildProcess: ChildProcess, + OS: OS, + Util: Util +}; + +let bscBin = Path.join("cli", "bsc"); + +let options = Object.fromEntries([[ + "ignore-runtime-tests", + { + type: "string" + } + ]]); + +let match = Nodeutil.parseArgs({ + args: process.argv.slice(2), + options: options +}); + +let values = match.values; + +let v = values["ignore-runtime-tests"]; + +let ignoreRuntimeTests = v !== undefined ? v.split(",").map(s => s.trim()) : []; + +async function run(command, args, options) { + let spawn = Child_process.spawn(command, args, options !== undefined ? Primitive_option.valFromOption(options) : undefined); + let stdout = []; + let stderr = []; + spawn.stdout.on("data", data => { + stdout.push(data); + }); + spawn.stderr.on("data", data => { + stderr.push(data); + }); + return await new Promise((resolve, reject) => { + spawn.once("error", (param, param$1) => reject({ + stdout: stdout, + stderr: stderr, + code: 1.0 + })); + spawn.once("close", (code, _signal) => resolve({ + stdout: stdout, + stderr: stderr, + code: code + })); + }); +} + +let SpawnAsync = { + run: run +}; + +function createFileInTempDir(id) { + return Path.join(Os.tmpdir(), id); +} + +async function compileTest(param, code) { + let match = await run(bscBin, [ + "-w", + "-3-109-44", + "-e", + code + ], undefined); + let stderr = match.stderr; + if (stderr.length > 0) { + return { + TAG: "Error", + _0: stderr.map(e => e.toString()).join("") + }; + } else { + return { + TAG: "Ok", + _0: match.stdout.map(e => e.toString()).join("") + }; + } +} + +async function runtimeTests(code) { + let match = await run("node", [ + "-e", + code, + "--input-type", + "commonjs" + ], { + cwd: process.cwd(), + timeout: 2000 + }); + let exitCode = match.code; + let stderr = match.stderr; + let stdout = match.stdout; + let std; + let exit = 0; + if (exitCode !== null) { + if (exitCode === 0.0 && stderr.length > 0) { + std = { + TAG: "Ok", + _0: stderr + }; + } else if (exitCode === 0.0) { + std = { + TAG: "Ok", + _0: stdout + }; + } else { + exit = 1; + } + } else { + exit = 1; + } + if (exit === 1) { + std = { + TAG: "Error", + _0: stderr.length > 0 ? stderr : stdout + }; + } + if (std.TAG === "Ok") { + return { + TAG: "Ok", + _0: std._0.map(e => e.toString()).join("") + }; + } else { + return { + TAG: "Error", + _0: std._0.map(e => e.toString()).join("") + }; + } +} + +function indentOutputCode(code) { + let indent = " ".repeat(2); + return code.split("\n").map(s => indent + s).join("\n"); +} + +function extractDocFromFile(file) { + let toolsBin = Path.join(process.cwd(), "cli", "rescript-tools"); + let spawn = Child_process.spawnSync(toolsBin, [ + "doc", + file + ]); + let output = spawn.stdout.toString(); + try { + return RescriptTools_Docgen.decodeFromJson(JSON.parse(output)); + } catch (raw_exn) { + let exn = Primitive_exceptions.internalToException(raw_exn); + if (exn.RE_EXN_ID === Exn.$$Error) { + return $$Error.panic("Failed to generate docstrings from " + file); + } + throw { + RE_EXN_ID: "Assert_failure", + _1: [ + "DocTest.res", + 204, + 9 + ], + Error: new Error() + }; + } +} + +function getExamples(param) { + let loop = (_items, _acc) => { + while (true) { + let acc = _acc; + let items = _items; + if (!items) { + return acc; + } + let match = items.hd; + switch (match.kind) { + case "value" : + _acc = { + hd: { + id: match.id, + kind: "value", + name: match.name, + docstrings: match.docstrings + }, + tl: acc + }; + _items = items.tl; + continue; + case "type" : + _acc = { + hd: { + id: match.id, + kind: "type", + name: match.name, + docstrings: match.docstrings + }, + tl: acc + }; + _items = items.tl; + continue; + case "module" : + _acc = { + hd: { + id: match.id, + kind: "module", + name: match.name, + docstrings: match.docstrings + }, + tl: acc + }; + _items = Belt_List.concatMany([ + items.tl, + List.fromArray(match.items) + ]); + continue; + case "moduleType" : + _acc = { + hd: { + id: match.id, + kind: "moduleType", + name: match.name, + docstrings: match.docstrings + }, + tl: acc + }; + _items = Belt_List.concatMany([ + items.tl, + List.fromArray(match.items) + ]); + continue; + case "moduleAlias" : + _acc = { + hd: { + id: match.id, + kind: "moduleAlias", + name: match.name, + docstrings: match.docstrings + }, + tl: acc + }; + _items = Belt_List.concatMany([ + items.tl, + List.fromArray(match.items) + ]); + continue; + } + }; + }; + return List.toArray(loop(List.fromArray(param.items), /* [] */0)).filter(param => param.docstrings.length > 0); +} + +function getCodeBlocks(example) { + let loopEndCodeBlock = (_lines, _acc) => { + while (true) { + let acc = _acc; + let lines = _lines; + if (!lines) { + return Pervasives.panic("Failed to find end of code block for " + example.kind + ": " + example.id); + } + let hd = lines.hd; + if (hd.trim().endsWith("```")) { + return acc; + } + _acc = { + hd: hd, + tl: acc + }; + _lines = lines.tl; + continue; + }; + }; + let loop = (_lines, _acc) => { + while (true) { + let acc = _acc; + let lines = _lines; + if (!lines) { + return acc; + } + let rest = lines.tl; + if (lines.hd.trim().startsWith("```res")) { + let code = loopEndCodeBlock(rest, /* [] */0); + _acc = { + hd: List.toArray(List.reverse(code)).join("\n"), + tl: acc + }; + _lines = rest; + continue; + } + _lines = rest; + continue; + }; + }; + return Belt_Array.reverse(List.toArray(loop(List.fromArray($$Array.reduce(example.docstrings, [], (acc, docstring) => acc.concat(docstring.split("\n")))), /* [] */0))).join("\n\n"); +} + +function chunkArray(array, chunkSize) { + let result = []; + let loop = _i => { + while (true) { + let i = _i; + if (i >= array.length) { + return; + } + result.push(array.slice(i, Math.min(i + chunkSize | 0, array.length))); + _i = i + chunkSize | 0; + continue; + }; + }; + loop(0); + return result; +} + +async function main() { + let files = Fs.readdirSync("runtime"); + let modules = $$Array.reduce(files.filter(f => { + if (f.startsWith("Js")) { + return false; + } else { + return !f.startsWith("RescriptTools"); + } + }).filter(f => { + if (f.endsWith(".res")) { + return true; + } else { + return f.endsWith(".resi"); + } + }), [], (acc, cur) => { + let isInterface = cur.endsWith(".resi"); + let resi = Path.join("runtime", cur + "i"); + if (!isInterface && Fs.existsSync(resi)) { + return acc.concat([cur + "i"]); + } else if (acc.includes(cur)) { + return acc; + } else { + return acc.concat([cur]); + } + }).map(f => getExamples(extractDocFromFile(Path.join("runtime", f)))).flat(); + let batchSize = (Os.cpus().length << 1); + let chuncks = chunkArray(modules, batchSize); + console.log("chuncks length", chuncks.length); + console.log("chunck part size", $$Array.reduce(chuncks, 0, (acc, cur) => acc + cur.length | 0)); + let context = { + contents: 0 + }; + let asyncIterator = $$AsyncIterator.make(async () => { + let currentValue = context.contents; + context.contents = currentValue + 1 | 0; + return { + done: currentValue === (chuncks.length - 1 | 0), + value: currentValue + }; + }); + let result = []; + let processMyAsyncIterator = async () => { + let $$break = false; + while (!$$break) { + let match = await asyncIterator.next(); + let value = match.value; + $$break = match.done; + if (value !== undefined) { + let c = chuncks[value]; + let a = await Promise.all(c.map(async example => { + let id = example.id.replaceAll(".", "__"); + let rescriptCode = getCodeBlocks(example); + let jsCode = await compileTest(id, rescriptCode); + return [ + example, + [ + rescriptCode, + jsCode + ] + ]; + })); + result.push(a); + } + + }; + }; + await processMyAsyncIterator(); + console.log("Compiation tests finished"); + let compilationResults = result.flat(); + let match = $$Array.reduce(compilationResults, [ + [], + [] + ], (acc, param) => { + let rhs = acc[1]; + let lhs = acc[0]; + let match = param[1]; + let jsCode = match[1]; + let example = param[0]; + if (jsCode.TAG === "Ok") { + lhs.push([ + example, + match[0], + jsCode._0 + ]); + } else { + rhs.push([ + example, + { + TAG: "ReScriptError", + _0: jsCode._0 + } + ]); + } + return [ + lhs, + rhs + ]; + }); + chunkArray(match[0], batchSize); + let runtimeErrors = []; + let allErrors = runtimeErrors.concat(match[1]); + allErrors.forEach(param => { + let errors = param[1]; + let example = param[0]; + let cyan = s => "\x1b[36m" + s + "\x1b[0m"; + let other = example.kind; + let kind = other === "moduleAlias" ? "module alias" : other; + let a; + if (errors.TAG === "ReScriptError") { + let err = errors._0.split("\n").filter((param, i) => i !== 2).join("\n"); + a = "\x1B[1;31merror\x1B[0m: failed to compile examples from " + kind + " " + cyan(example.id) + "\n" + err; + } else { + let indent = " ".repeat(2); + a = "\x1B[1;31mruntime error\x1B[0m: failed to run examples from " + kind + " " + cyan(example.id) + "\n\n" + indent + "\x1b[36mReScript\x1b[0m\n\n" + indentOutputCode(errors.rescript) + "\n\n" + indent + "\x1b[36mCompiled Js\x1b[0m\n\n" + indentOutputCode(errors.js) + "\n\n" + indent + "\x1B[1;31mstacktrace\x1B[0m\n\n" + indentOutputCode(errors.error) + "\n"; + } + process.stderr.write(a); + }); + let someError = allErrors.length > 0; + if (someError) { + return 1; + } else { + return 0; + } +} + +let exitCode = await main(); + +process.exit(exitCode); + +let Docgen; + +export { + Node, + Docgen, + bscBin, + options, + values, + ignoreRuntimeTests, + SpawnAsync, + createFileInTempDir, + compileTest, + runtimeTests, + indentOutputCode, + extractDocFromFile, + getExamples, + getCodeBlocks, + chunkArray, + main, + exitCode, +} +/* bscBin Not a pure module */ diff --git a/tests/docstrings_examples/rescript.json b/tests/docstrings_examples/rescript.json new file mode 100644 index 0000000000..e987791ab6 --- /dev/null +++ b/tests/docstrings_examples/rescript.json @@ -0,0 +1,11 @@ +{ + "name": "doc-test-examples", + "sources": { + "dir": "." + }, + "package-specs": { + "module": "esmodule", + "in-source": true + }, + "suffix": ".res.mjs" +} diff --git a/tests/tests/src/test_pervasive.mjs b/tests/tests/src/test_pervasive.mjs index 0653322903..0b80ec595f 100644 --- a/tests/tests/src/test_pervasive.mjs +++ b/tests/tests/src/test_pervasive.mjs @@ -111,7 +111,8 @@ let Pervasives$1 = { bool_of_string_opt: Pervasives.bool_of_string_opt, int_of_string_opt: Pervasives.int_of_string_opt, $at: Pervasives.$at, - panic: Pervasives.panic + panic: Pervasives.panic, + assertEqual: Pervasives.assertEqual }; function a0(prim) { diff --git a/tests/tests/src/test_pervasives3.mjs b/tests/tests/src/test_pervasives3.mjs index 6b8a65b676..3b414a88c5 100644 --- a/tests/tests/src/test_pervasives3.mjs +++ b/tests/tests/src/test_pervasives3.mjs @@ -24,6 +24,7 @@ let Pervasives$1 = { int_of_string_opt: Pervasives.int_of_string_opt, $at: Pervasives.$at, panic: Pervasives.panic, + assertEqual: Pervasives.assertEqual, length: Belt_List.length, size: Belt_List.size, head: Belt_List.head,