aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gleam/iterator.gleam286
-rw-r--r--src/gleam/string.gleam66
-rw-r--r--src/gleam_stdlib.js8
-rw-r--r--test/gleam/base_test.gleam44
-rw-r--r--test/gleam/function_test.gleam183
-rw-r--r--test/gleam/iterator_test.gleam730
-rw-r--r--test/gleam/string_test.gleam20
7 files changed, 668 insertions, 669 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam
index e7405bb..4f8b7ff 100644
--- a/src/gleam/iterator.gleam
+++ b/src/gleam/iterator.gleam
@@ -922,159 +922,159 @@ if erlang {
|> fold(map.new(), group_updater(key))
|> map.map_values(fn(_, group) { list.reverse(group) })
}
+}
- /// This function acts similar to fold, but does not take an initial state.
- /// Instead, it starts from the first yielded element
- /// and combines it with each subsequent element in turn using the given function.
- /// The function is called as f(current_element, accumulator).
- ///
- /// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator.
- ///
- /// ## Examples
- ///
- /// > from_list([]) |> reduce(fn(x, y) { x + y })
- /// Error(Nil)
- ///
- /// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(x, y) { x + y })
- /// Ok(15)
- ///
- pub fn reduce(
- over iterator: Iterator(e),
- with f: fn(e, e) -> e,
- ) -> Result(e, Nil) {
- case iterator.continuation() {
- Stop -> Error(Nil)
- Continue(e, next) ->
- do_fold(next, f, e)
- |> Ok
- }
+/// This function acts similar to fold, but does not take an initial state.
+/// Instead, it starts from the first yielded element
+/// and combines it with each subsequent element in turn using the given function.
+/// The function is called as f(current_element, accumulator).
+///
+/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator.
+///
+/// ## Examples
+///
+/// > from_list([]) |> reduce(fn(x, y) { x + y })
+/// Error(Nil)
+///
+/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(x, y) { x + y })
+/// Ok(15)
+///
+pub fn reduce(
+ over iterator: Iterator(e),
+ with f: fn(e, e) -> e,
+) -> Result(e, Nil) {
+ case iterator.continuation() {
+ Stop -> Error(Nil)
+ Continue(e, next) ->
+ do_fold(next, f, e)
+ |> Ok
}
+}
- /// Returns the last element in the given iterator.
- ///
- /// Returns `Error(Nil)` if the iterator is empty.
- ///
- /// This function runs in linear time.
- ///
- /// ## Examples
- ///
- /// > empty() |> last
- /// Error(Nil)
- ///
- /// > range(1, 10) |> last
- /// Ok(9)
- ///
- pub fn last(iterator: Iterator(element)) -> Result(element, Nil) {
- iterator
- |> reduce(fn(elem, _) { elem })
- }
+/// Returns the last element in the given iterator.
+///
+/// Returns `Error(Nil)` if the iterator is empty.
+///
+/// This function runs in linear time.
+///
+/// ## Examples
+///
+/// > empty() |> last
+/// Error(Nil)
+///
+/// > range(1, 10) |> last
+/// Ok(9)
+///
+pub fn last(iterator: Iterator(element)) -> Result(element, Nil) {
+ iterator
+ |> reduce(fn(elem, _) { elem })
+}
- /// Creates an iterator that yields no elements.
- ///
- /// ## Examples
- ///
- /// > empty() |> to_list
- /// []
- ///
- pub fn empty() -> Iterator(element) {
- Iterator(stop)
- }
+/// Creates an iterator that yields no elements.
+///
+/// ## Examples
+///
+/// > empty() |> to_list
+/// []
+///
+pub fn empty() -> Iterator(element) {
+ Iterator(stop)
+}
- /// Creates an iterator that yields exactly one element provided by calling the given function.
- ///
- /// ## Examples
- ///
- /// > once(fn() { 1 }) |> to_list
- /// [1]
- ///
- pub fn once(f: fn() -> element) -> Iterator(element) {
- fn() { Continue(f(), stop) }
- |> Iterator
- }
+/// Creates an iterator that yields exactly one element provided by calling the given function.
+///
+/// ## Examples
+///
+/// > once(fn() { 1 }) |> to_list
+/// [1]
+///
+pub fn once(f: fn() -> element) -> Iterator(element) {
+ fn() { Continue(f(), stop) }
+ |> Iterator
+}
- /// Creates an iterator that yields the given element exactly once.
- ///
- /// ## Examples
- ///
- /// > single(1) |> to_list
- /// [1]
- ///
- pub fn single(elem: element) -> Iterator(element) {
- once(fn() { elem })
- }
+/// Creates an iterator that yields the given element exactly once.
+///
+/// ## Examples
+///
+/// > single(1) |> to_list
+/// [1]
+///
+pub fn single(elem: element) -> Iterator(element) {
+ once(fn() { elem })
+}
- fn do_interleave(
- current: fn() -> Action(element),
- next: fn() -> Action(element),
- ) -> Action(element) {
- case current() {
- Stop -> next()
- Continue(e, next_other) ->
- Continue(e, fn() { do_interleave(next, next_other) })
- }
+fn do_interleave(
+ current: fn() -> Action(element),
+ next: fn() -> Action(element),
+) -> Action(element) {
+ case current() {
+ Stop -> next()
+ Continue(e, next_other) ->
+ Continue(e, fn() { do_interleave(next, next_other) })
}
+}
- /// Creates an iterator that alternates between the two given iterators
- /// until both have run out.
- ///
- /// ## Examples
- ///
- /// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list
- /// [1, 11, 2, 12, 3, 13, 4, 14]
- ///
- /// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list
- /// [1, 100, 2, 3, 4]
- ///
- pub fn interleave(
- left: Iterator(element),
- with right: Iterator(element),
- ) -> Iterator(element) {
- fn() { do_interleave(left.continuation, right.continuation) }
- |> Iterator
- }
+/// Creates an iterator that alternates between the two given iterators
+/// until both have run out.
+///
+/// ## Examples
+///
+/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list
+/// [1, 11, 2, 12, 3, 13, 4, 14]
+///
+/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list
+/// [1, 100, 2, 3, 4]
+///
+pub fn interleave(
+ left: Iterator(element),
+ with right: Iterator(element),
+) -> Iterator(element) {
+ fn() { do_interleave(left.continuation, right.continuation) }
+ |> Iterator
+}
- fn do_fold_until(
- continuation: fn() -> Action(e),
- f: fn(e, acc) -> list.ContinueOrStop(acc),
- accumulator: acc,
- ) -> acc {
- case continuation() {
- Stop -> accumulator
- Continue(elem, next) ->
- case f(elem, accumulator) {
- list.Continue(accumulator) -> do_fold_until(next, f, accumulator)
- list.Stop(accumulator) -> accumulator
- }
- }
+fn do_fold_until(
+ continuation: fn() -> Action(e),
+ f: fn(e, acc) -> list.ContinueOrStop(acc),
+ accumulator: acc,
+) -> acc {
+ case continuation() {
+ Stop -> accumulator
+ Continue(elem, next) ->
+ case f(elem, accumulator) {
+ list.Continue(accumulator) -> do_fold_until(next, f, accumulator)
+ list.Stop(accumulator) -> accumulator
+ }
}
+}
- /// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given
- /// function on each element in turn, but uses a `list.ContinueOrStop` to determine
- /// whether or not to keep iterating.
- ///
- /// If called on an iterator of infinite length then this function will only ever
- /// return if the give function returns list.Stop.
- ///
- ///
- /// ## Examples
- /// > let f = fn(e, acc) {
- /// > case e {
- /// > _ if e < 4 -> list.Continue(e + acc)
- /// > _ -> list.Stop(acc)
- /// > }
- /// > }
- /// >
- /// > [1, 2, 3, 4]
- /// > |> from_list
- /// > |> iterator.fold_until(from: acc, with: f)
- /// 6
- ///
- pub fn fold_until(
- over iterator: Iterator(e),
- from initial: acc,
- with f: fn(e, acc) -> list.ContinueOrStop(acc),
- ) -> acc {
- iterator.continuation
- |> do_fold_until(f, initial)
- }
+/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given
+/// function on each element in turn, but uses a `list.ContinueOrStop` to determine
+/// whether or not to keep iterating.
+///
+/// If called on an iterator of infinite length then this function will only ever
+/// return if the give function returns list.Stop.
+///
+///
+/// ## Examples
+/// > let f = fn(e, acc) {
+/// > case e {
+/// > _ if e < 4 -> list.Continue(e + acc)
+/// > _ -> list.Stop(acc)
+/// > }
+/// > }
+/// >
+/// > [1, 2, 3, 4]
+/// > |> from_list
+/// > |> iterator.fold_until(from: acc, with: f)
+/// 6
+///
+pub fn fold_until(
+ over iterator: Iterator(e),
+ from initial: acc,
+ with f: fn(e, acc) -> list.ContinueOrStop(acc),
+) -> acc {
+ iterator.continuation
+ |> do_fold_until(f, initial)
}
diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam
index 0703dd7..d9d2c63 100644
--- a/src/gleam/string.gleam
+++ b/src/gleam/string.gleam
@@ -2,7 +2,7 @@
//// text surrounded by `"double quotes"`.
import gleam/string_builder
-import gleam/iterator
+import gleam/iterator.{Iterator}
import gleam/list
import gleam/order
import gleam/result
@@ -494,28 +494,13 @@ pub fn join(strings: List(String), with separator: String) -> String {
/// > pad_left("121", to: 2, with: ".")
/// "121"
///
-pub fn pad_left(string: String, to length: Int, with pad_string: String) {
- do_pad_left(string, length, pad_string)
-}
-
-if erlang {
- type Direction {
- Leading
- Trailing
- Both
- }
-
- fn do_pad_left(string: String, to length: Int, with pad_string: String) {
- erl_pad(string, length, Leading, pad_string)
- }
-
- external fn erl_pad(String, Int, Direction, String) -> String =
- "gleam_stdlib" "string_pad"
-}
-
-if javascript {
- external fn do_pad_left(String, Int, String) -> String =
- "../gleam_stdlib.js" "pad_left"
+pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) {
+ let current_length = length(string)
+ let to_pad_length = desired_length - current_length
+ padding(to_pad_length, pad_string)
+ |> iterator.append(iterator.single(string))
+ |> iterator.to_list
+ |> concat
}
/// Pads a string on the right until it has a given length.
@@ -531,19 +516,26 @@ if javascript {
/// > pad_right("121", to: 2, with: ".")
/// "121"
///
-pub fn pad_right(string: String, to length: Int, with pad_string: String) {
- do_pad_right(string, length, pad_string)
-}
-
-if erlang {
- fn do_pad_right(string: String, to length: Int, with pad_string: String) {
- erl_pad(string, length, Trailing, pad_string)
- }
+pub fn pad_right(
+ string: String,
+ to desired_length: Int,
+ with pad_string: String,
+) {
+ let current_length = length(string)
+ let to_pad_length = desired_length - current_length
+ iterator.single(string)
+ |> iterator.append(padding(to_pad_length, pad_string))
+ |> iterator.to_list
+ |> concat
}
-if javascript {
- external fn do_pad_right(String, Int, String) -> String =
- "../gleam_stdlib.js" "pad_right"
+fn padding(size: Int, pad_string: String) -> Iterator(String) {
+ let pad_length = length(pad_string)
+ let num_pads = size / pad_length
+ let extra = size % pad_length
+ iterator.repeat(pad_string)
+ |> iterator.take(num_pads)
+ |> iterator.append(iterator.single(slice(pad_string, 0, extra)))
}
/// Removes whitespace on both sides of a String.
@@ -562,6 +554,12 @@ if erlang {
erl_trim(string, Both)
}
+ type Direction {
+ Leading
+ Trailing
+ Both
+ }
+
external fn erl_trim(String, Direction) -> String =
"string" "trim"
}
diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js
index 65dd45c..89908de 100644
--- a/src/gleam_stdlib.js
+++ b/src/gleam_stdlib.js
@@ -158,11 +158,3 @@ export function trim_left(string) {
export function trim_right(string) {
return string.trimRight();
}
-
-export function pad_left(string, length, pad) {
- return string.padStart(length, pad);
-}
-
-export function pad_right(string, length, pad) {
- return string.padEnd(length, pad);
-}
diff --git a/test/gleam/base_test.gleam b/test/gleam/base_test.gleam
index 80f0024..dd59196 100644
--- a/test/gleam/base_test.gleam
+++ b/test/gleam/base_test.gleam
@@ -1,31 +1,23 @@
if erlang {
import gleam/base
- import gleam/bit_string.{BitString}
import gleam/io
import gleam/list
import gleam/should
- external fn list_to_binary(List(Int)) -> BitString =
- "erlang" "list_to_binary"
-
pub fn encode64_test() {
- [255, 127, 254, 252]
- |> list_to_binary()
+ <<255, 127, 254, 252>>
|> base.encode64(True)
|> should.equal("/3/+/A==")
- [255, 127, 254, 252]
- |> list_to_binary()
+ <<255, 127, 254, 252>>
|> base.encode64(False)
|> should.equal("/3/+/A")
- [0, 0, 0]
- |> list_to_binary()
+ <<0, 0, 0>>
|> base.encode64(True)
|> should.equal("AAAA")
- []
- |> list_to_binary()
+ <<>>
|> base.encode64(True)
|> should.equal("")
}
@@ -33,19 +25,19 @@ if erlang {
pub fn decode64_test() {
"/3/+/A=="
|> base.decode64()
- |> should.equal(Ok(list_to_binary([255, 127, 254, 252])))
+ |> should.equal(Ok(<<255, 127, 254, 252>>))
"/3/+/A"
|> base.decode64()
- |> should.equal(Ok(list_to_binary([255, 127, 254, 252])))
+ |> should.equal(Ok(<<255, 127, 254, 252>>))
"AAAA"
|> base.decode64()
- |> should.equal(Ok(list_to_binary([0, 0, 0])))
+ |> should.equal(Ok(<<0, 0, 0>>))
""
|> base.decode64()
- |> should.equal(Ok(list_to_binary([])))
+ |> should.equal(Ok(<<>>))
")!"
|> base.decode64()
@@ -53,23 +45,19 @@ if erlang {
}
pub fn url_encode64_test() {
- [255, 127, 254, 252]
- |> list_to_binary()
+ <<255, 127, 254, 252>>
|> base.url_encode64(True)
|> should.equal("_3_-_A==")
- [255, 127, 254, 252]
- |> list_to_binary()
+ <<255, 127, 254, 252>>
|> base.url_encode64(False)
|> should.equal("_3_-_A")
- [0, 0, 0]
- |> list_to_binary()
+ <<0, 0, 0>>
|> base.url_encode64(True)
|> should.equal("AAAA")
- []
- |> list_to_binary()
+ <<>>
|> base.url_encode64(True)
|> should.equal("")
}
@@ -77,19 +65,19 @@ if erlang {
pub fn url_decode64_test() {
"_3_-_A=="
|> base.url_decode64()
- |> should.equal(Ok(list_to_binary([255, 127, 254, 252])))
+ |> should.equal(Ok(<<255, 127, 254, 252>>))
"_3_-_A"
|> base.url_decode64()
- |> should.equal(Ok(list_to_binary([255, 127, 254, 252])))
+ |> should.equal(Ok(<<255, 127, 254, 252>>))
"AAAA"
|> base.url_decode64()
- |> should.equal(Ok(list_to_binary([0, 0, 0])))
+ |> should.equal(Ok(<<0, 0, 0>>))
""
|> base.url_decode64()
- |> should.equal(Ok(list_to_binary([])))
+ |> should.equal(Ok(<<>>))
")!"
|> base.url_decode64()
diff --git a/test/gleam/function_test.gleam b/test/gleam/function_test.gleam
index e4a368c..0b3bd8c 100644
--- a/test/gleam/function_test.gleam
+++ b/test/gleam/function_test.gleam
@@ -1,112 +1,109 @@
-if erlang {
- // TODO: JavaScript
- import gleam/should
- import gleam/dynamic
- import gleam/function
- import gleam/int
- import gleam/list
- import gleam/result
- import gleam/string
-
- pub fn compose_test() {
- let add_two = fn(int: Int) { int + 2 }
- let add_three = fn(int: Int) { int + 3 }
-
- let add_five = function.compose(add_two, add_three)
-
- 1
- |> add_five
- |> should.equal(6)
-
- // Takes a list of ints and returns the head as a string (if there is one, or
- // else "0" if there is not)
- let head_to_string =
- list.head
- |> function.compose(result.unwrap(_, 0))
- |> function.compose(int.to_string)
-
- [1]
- |> head_to_string
- |> should.equal("1")
-
- []
- |> head_to_string
- |> should.equal("0")
- }
+import gleam/should
+import gleam/dynamic
+import gleam/function
+import gleam/int
+import gleam/list
+import gleam/result
+import gleam/string
+
+pub fn compose_test() {
+ let add_two = fn(int: Int) { int + 2 }
+ let add_three = fn(int: Int) { int + 3 }
+
+ let add_five = function.compose(add_two, add_three)
+
+ 1
+ |> add_five
+ |> should.equal(6)
+
+ // Takes a list of ints and returns the head as a string (if there is one, or
+ // else "0" if there is not)
+ let head_to_string =
+ list.head
+ |> function.compose(result.unwrap(_, 0))
+ |> function.compose(int.to_string)
+
+ [1]
+ |> head_to_string
+ |> should.equal("1")
+
+ []
+ |> head_to_string
+ |> should.equal("0")
+}
- pub fn curry2_test() {
- let fun = fn(a, b) { a + b }
- let curried = function.curry2(fun)
+pub fn curry2_test() {
+ let fun = fn(a, b) { a + b }
+ let curried = function.curry2(fun)
- curried(1)(2)
- |> should.equal(3)
- }
+ curried(1)(2)
+ |> should.equal(3)
+}
- pub fn curry3_test() {
- let fun = fn(a, b, c) { a + b + c }
- let curried = function.curry3(fun)
+pub fn curry3_test() {
+ let fun = fn(a, b, c) { a + b + c }
+ let curried = function.curry3(fun)
- curried(1)(2)(4)
- |> should.equal(7)
- }
+ curried(1)(2)(4)
+ |> should.equal(7)
+}
- pub fn curry4_test() {
- let fun = fn(a, b, c, d) { a + b + c + d }
- let curried = function.curry4(fun)
+pub fn curry4_test() {
+ let fun = fn(a, b, c, d) { a + b + c + d }
+ let curried = function.curry4(fun)
- curried(1)(2)(4)(8)
- |> should.equal(15)
- }
+ curried(1)(2)(4)(8)
+ |> should.equal(15)
+}
- pub fn curry5_test() {
- let fun = fn(a, b, c, d, e) { a + b + c + d + e }
- let curried = function.curry5(fun)
+pub fn curry5_test() {
+ let fun = fn(a, b, c, d, e) { a + b + c + d + e }
+ let curried = function.curry5(fun)
- curried(1)(2)(4)(8)(16)
- |> should.equal(31)
- }
+ curried(1)(2)(4)(8)(16)
+ |> should.equal(31)
+}
- pub fn curry6_test() {
- let fun = fn(a, b, c, d, e, f) { a + b + c + d + e + f }
- let curried = function.curry6(fun)
+pub fn curry6_test() {
+ let fun = fn(a, b, c, d, e, f) { a + b + c + d + e + f }
+ let curried = function.curry6(fun)
- curried(1)(2)(4)(8)(16)(32)
- |> should.equal(63)
- }
+ curried(1)(2)(4)(8)(16)(32)
+ |> should.equal(63)
+}
- pub fn flip_test() {
- let fun = fn(s: String, i: Int) {
- s
- |> string.append("String: '", _)
- |> string.append("', Int: '")
- |> string.append(int.to_string(i))
- |> string.append("'")
- }
+pub fn flip_test() {
+ let fun = fn(s: String, i: Int) {
+ s
+ |> string.append("String: '", _)
+ |> string.append("', Int: '")
+ |> string.append(int.to_string(i))
+ |> string.append("'")
+ }
- let flipped_fun = function.flip(fun)
+ let flipped_fun = function.flip(fun)
- fun("Bob", 1)
- |> should.equal("String: 'Bob', Int: '1'")
+ fun("Bob", 1)
+ |> should.equal("String: 'Bob', Int: '1'")
- flipped_fun(2, "Alice")
- |> should.equal("String: 'Alice', Int: '2'")
- }
+ flipped_fun(2, "Alice")
+ |> should.equal("String: 'Alice', Int: '2'")
+}
- pub fn identity_test() {
- 1
- |> function.identity
- |> should.equal(1)
+pub fn identity_test() {
+ 1
+ |> function.identity
+ |> should.equal(1)
- ""
- |> function.identity
- |> should.equal("")
+ ""
+ |> function.identity
+ |> should.equal("")
- []
- |> function.identity
- |> should.equal([])
+ []
+ |> function.identity
+ |> should.equal([])
- #(1, 2.0)
- |> function.identity
- |> should.equal(#(1, 2.0))
- }
+ #(1, 2.0)
+ |> function.identity
+ |> should.equal(#(1, 2.0))
}
diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam
index 50d1c99..8de4251 100644
--- a/test/gleam/iterator_test.gleam
+++ b/test/gleam/iterator_test.gleam
@@ -1,370 +1,378 @@
+import gleam/should
+import gleam/iterator.{Done, Next}
+import gleam/list
+
if erlang {
- import gleam/should
- import gleam/iterator.{Done, Next}
- import gleam/list
import gleam/map
+}
- // a |> from_list |> to_list == a
- pub fn to_from_list_test() {
- let test = fn(subject) {
- subject
- |> iterator.from_list
- |> iterator.to_list
- |> should.equal(subject)
- }
-
- test([])
- test([1])
- test([1, 2])
- test([1, 2, 4, 8])
+// a |> from_list |> to_list == a
+pub fn to_from_list_test() {
+ let test = fn(subject) {
+ subject
+ |> iterator.from_list
+ |> iterator.to_list
+ |> should.equal(subject)
}
- pub fn step_test() {
- let test = fn(subject) {
- let step =
- subject
- |> iterator.from_list
- |> iterator.step
-
- case subject {
- [] ->
- step
- |> should.equal(Done)
-
- [h, ..t] ->
- step
- |> should.equal(Next(h, iterator.from_list(t)))
- }
- }
-
- test([])
- test([1])
- test([1, 2])
- test([1, 2, 3])
- }
+ test([])
+ test([1])
+ test([1, 2])
+ test([1, 2, 4, 8])
+}
- // a |> from_list |> take(n) == a |> list.take(_, n)
- pub fn take_test() {
- let test = fn(n, subject) {
+pub fn step_test() {
+ let test = fn(subject) {
+ let step =
subject
|> iterator.from_list
- |> iterator.take(n)
- |> iterator.to_list
- |> should.equal(list.take(subject, n))
+ |> iterator.step
+
+ case subject {
+ [] ->
+ step
+ |> should.equal(Done)
+
+ [h, ..t] -> {
+ assert Next(h2, t2) = step
+ h
+ |> should.equal(h2)
+ t2
+ |> iterator.to_list
+ |> should.equal(t)
+ }
}
-
- test(0, [])
- test(1, [])
- test(-1, [])
- test(0, [0])
- test(1, [0])
- test(-1, [0])
- test(0, [0, 1, 2, 3, 4])
- test(1, [0, 1, 2, 3, 4])
- test(2, [0, 1, 2, 3, 4])
- test(22, [0, 1, 2, 3, 4])
}
- // a |> from_list |> fold(a, f) == a |> list.fold(_, a, f)
- pub fn fold_test() {
- let test = fn(subject, acc, f) {
- subject
- |> iterator.from_list
- |> iterator.fold(acc, f)
- |> should.equal(list.fold(subject, acc, f))
- }
-
- let f = fn(e, acc) { [e, ..acc] }
- test([], [], f)
- test([1], [], f)
- test([1, 2, 3], [], f)
- test([1, 2, 3, 4, 5, 6, 7, 8], [], f)
- }
+ test([])
+ test([1])
+ test([1, 2])
+ test([1, 2, 3])
+}
- // a |> from_list |> map(f) |> to_list == a |> list.map(_, f)
- pub fn map_test() {
- let test = fn(subject, f) {
- subject
- |> iterator.from_list
- |> iterator.map(f)
- |> iterator.to_list
- |> should.equal(list.map(subject, f))
- }
+// a |> from_list |> take(n) == a |> list.take(_, n)
+pub fn take_test() {
+ let test = fn(n, subject) {
+ subject
+ |> iterator.from_list
+ |> iterator.take(n)
+ |> iterator.to_list
+ |> should.equal(list.take(subject, n))
+ }
+
+ test(0, [])
+ test(1, [])
+ test(-1, [])
+ test(0, [0])
+ test(1, [0])
+ test(-1, [0])
+ test(0, [0, 1, 2, 3, 4])
+ test(1, [0, 1, 2, 3, 4])
+ test(2, [0, 1, 2, 3, 4])
+ test(22, [0, 1, 2, 3, 4])
+}
- let f = fn(e) { e * 2 }
- test([], f)
- test([1], f)
- test([1, 2, 3], f)
- test([1, 2, 3, 4, 5, 6, 7, 8], f)
+// a |> from_list |> fold(a, f) == a |> list.fold(_, a, f)
+pub fn fold_test() {
+ let test = fn(subject, acc, f) {
+ subject
+ |> iterator.from_list
+ |> iterator.fold(acc, f)
+ |> should.equal(list.fold(subject, acc, f))
}
- // a |> from_list |> flat_map(f) |> to_list ==
- // a |> list.map(f) |> list.map(to_list) |> list.flatten
- pub fn flat_map_test() {
- let test = fn(subject, f) {
- subject
- |> iterator.from_list
- |> iterator.flat_map(f)
- |> iterator.to_list
- |> should.equal(
- subject
- |> list.map(f)
- |> list.map(iterator.to_list)
- |> list.flatten,
- )
- }
-
- let f = fn(i) { iterator.range(i, i + 2) }
+ let f = fn(e, acc) { [e, ..acc] }
+ test([], [], f)
+ test([1], [], f)
+ test([1, 2, 3], [], f)
+ test([1, 2, 3, 4, 5, 6, 7, 8], [], f)
+}
- test([], f)
- test([1], f)
- test([1, 2], f)
+// a |> from_list |> map(f) |> to_list == a |> list.map(_, f)
+pub fn map_test() {
+ let test = fn(subject, f) {
+ subject
+ |> iterator.from_list
+ |> iterator.map(f)
+ |> iterator.to_list
+ |> should.equal(list.map(subject, f))
}
- // a |> from_list |> append(from_list(b)) |> to_list == list.flatten([a, b])
- pub fn append_test() {
- let test = fn(left, right) {
- left
- |> iterator.from_list
- |> iterator.append(iterator.from_list(right))
- |> iterator.to_list
- |> should.equal(list.flatten([left, right]))
- }
+ let f = fn(e) { e * 2 }
+ test([], f)
+ test([1], f)
+ test([1, 2, 3], f)
+ test([1, 2, 3, 4, 5, 6, 7, 8], f)
+}
- test([], [])
- test([1], [2])
- test([1, 2], [3, 4])
+// a |> from_list |> flat_map(f) |> to_list ==
+// a |> list.map(f) |> list.map(to_list) |> list.flatten
+pub fn flat_map_test() {
+ let test = fn(subject, f) {
+ subject
+ |> iterator.from_list
+ |> iterator.flat_map(f)
+ |> iterator.to_list
+ |> should.equal(
+ subject
+ |> list.map(f)
+ |> list.map(iterator.to_list)
+ |> list.flatten,
+ )
}
- // a |> list.map(from_list) |> flatten |> to_list == list.flatten(a)
- pub fn flatten_test() {
- let test = fn(lists) {
- lists
- |> list.map(iterator.from_list)
- |> iterator.from_list
- |> iterator.flatten
- |> iterator.to_list
- |> should.equal(list.flatten(lists))
- }
-
- test([[], []])
- test([[1], [2]])
- test([[1, 2], [3, 4]])
- }
+ let f = fn(i) { iterator.range(i, i + 2) }
- // a |> from_list |> filter(f) |> to_list == a |> list.filter(_, f)
- pub fn filter_test() {
- let test = fn(subject, f) {
- subject
- |> iterator.from_list
- |> iterator.filter(f)
- |> iterator.to_list
- |> should.equal(list.filter(subject, f))
- }
+ test([], f)
+ test([1], f)
+ test([1, 2], f)
+}
- let even = fn(x) { x % 2 == 0 }
- test([], even)
- test([1], even)
- test([1, 2], even)
- test([1, 2, 3], even)
- test([1, 2, 3, 4], even)
- test([1, 2, 3, 4, 5], even)
- test([1, 2, 3, 4, 5, 6], even)
+// a |> from_list |> append(from_list(b)) |> to_list == list.flatten([a, b])
+pub fn append_test() {
+ let test = fn(left, right) {
+ left
+ |> iterator.from_list
+ |> iterator.append(iterator.from_list(right))
+ |> iterator.to_list
+ |> should.equal(list.flatten([left, right]))
}
- pub fn repeat_test() {
- 1
- |> iterator.repeat
- |> iterator.take(5)
+ test([], [])
+ test([1], [2])
+ test([1, 2], [3, 4])
+}
+
+// a |> list.map(from_list) |> flatten |> to_list == list.flatten(a)
+pub fn flatten_test() {
+ let test = fn(lists) {
+ lists
+ |> list.map(iterator.from_list)
+ |> iterator.from_list
+ |> iterator.flatten
|> iterator.to_list
- |> should.equal([1, 1, 1, 1, 1])
+ |> should.equal(list.flatten(lists))
}
- pub fn cycle_test() {
- [1, 2, 3]
+ test([[], []])
+ test([[1], [2]])
+ test([[1, 2], [3, 4]])
+}
+
+// a |> from_list |> filter(f) |> to_list == a |> list.filter(_, f)
+pub fn filter_test() {
+ let test = fn(subject, f) {
+ subject
|> iterator.from_list
- |> iterator.cycle
- |> iterator.take(9)
+ |> iterator.filter(f)
|> iterator.to_list
- |> should.equal([1, 2, 3, 1, 2, 3, 1, 2, 3])
+ |> should.equal(list.filter(subject, f))
}
- pub fn unfold_test() {
- iterator.unfold(2, fn(acc) { iterator.Next(acc, acc * 2) })
- |> iterator.take(5)
- |> iterator.to_list
- |> should.equal([2, 4, 8, 16, 32])
+ let even = fn(x) { x % 2 == 0 }
+ test([], even)
+ test([1], even)
+ test([1, 2], even)
+ test([1, 2, 3], even)
+ test([1, 2, 3, 4], even)
+ test([1, 2, 3, 4, 5], even)
+ test([1, 2, 3, 4, 5, 6], even)
+}
- iterator.unfold(2, fn(_) { iterator.Done })
- |> iterator.take(5)
- |> iterator.to_list
- |> should.equal([])
+pub fn repeat_test() {
+ 1
+ |> iterator.repeat
+ |> iterator.take(5)
+ |> iterator.to_list
+ |> should.equal([1, 1, 1, 1, 1])
+}
- fn(n) {
- case n {
- 0 -> iterator.Done
- n -> iterator.Next(element: n, accumulator: n - 1)
- }
- }
- |> iterator.unfold(from: 5)
- |> iterator.to_list
- |> should.equal([5, 4, 3, 2, 1])
- }
+pub fn cycle_test() {
+ [1, 2, 3]
+ |> iterator.from_list
+ |> iterator.cycle
+ |> iterator.take(9)
+ |> iterator.to_list
+ |> should.equal([1, 2, 3, 1, 2, 3, 1, 2, 3])
+}
- pub fn range_test() {
- let test = fn(a, b, expected) {
- iterator.range(a, b)
- |> iterator.to_list
- |> should.equal(expected)
+pub fn unfold_test() {
+ iterator.unfold(2, fn(acc) { iterator.Next(acc, acc * 2) })
+ |> iterator.take(5)
+ |> iterator.to_list
+ |> should.equal([2, 4, 8, 16, 32])
+
+ iterator.unfold(2, fn(_) { iterator.Done })
+ |> iterator.take(5)
+ |> iterator.to_list
+ |> should.equal([])
+
+ fn(n) {
+ case n {
+ 0 -> iterator.Done
+ n -> iterator.Next(element: n, accumulator: n - 1)
}
-
- test(0, 0, [])
- test(1, 1, [])
- test(-1, -1, [])
- test(0, 1, [0])
- test(0, 5, [0, 1, 2, 3, 4])
- test(1, -5, [1, 0, -1, -2, -3, -4])
}
+ |> iterator.unfold(from: 5)
+ |> iterator.to_list
+ |> should.equal([5, 4, 3, 2, 1])
+}
- pub fn drop_test() {
- iterator.range(0, 10)
- |> iterator.drop(5)
+pub fn range_test() {
+ let test = fn(a, b, expected) {
+ iterator.range(a, b)
|> iterator.to_list
- |> should.equal([5, 6, 7, 8, 9])
+ |> should.equal(expected)
}
- type Cat {
- Cat(id: Int)
- }
-
- pub fn find_test() {
- iterator.range(0, 10)
- |> iterator.find(fn(e) { e == 5 })
- |> should.equal(Ok(5))
-
- iterator.range(0, 10)
- |> iterator.find(fn(e) { e > 10 })
- |> should.equal(Error(Nil))
-
- iterator.empty()
- |> iterator.find(fn(_x) { True })
- |> should.equal(Error(Nil))
+ test(0, 0, [])
+ test(1, 1, [])
+ test(-1, -1, [])
+ test(0, 1, [0])
+ test(0, 5, [0, 1, 2, 3, 4])
+ test(1, -5, [1, 0, -1, -2, -3, -4])
+}
- iterator.unfold(
- Cat(id: 1),
- fn(cat: Cat) { iterator.Next(cat, Cat(id: cat.id + 1)) },
- )
- |> iterator.find(fn(cat: Cat) { cat.id == 10 })
- |> should.equal(Ok(Cat(id: 10)))
- }
+pub fn drop_test() {
+ iterator.range(0, 10)
+ |> iterator.drop(5)
+ |> iterator.to_list
+ |> should.equal([5, 6, 7, 8, 9])
+}
- pub fn index_test() {
- iterator.from_list(["a", "b", "c"])
- |> iterator.index
- |> iterator.to_list
- |> should.equal([#(0, "a"), #(1, "b"), #(2, "c")])
- }
+type Cat {
+ Cat(id: Int)
+}
- pub fn iterate_test() {
- fn(x) { x * 3 }
- |> iterator.iterate(from: 1)
- |> iterator.take(5)
- |> iterator.to_list
- |> should.equal([1, 3, 9, 27, 81])
- }
+pub fn find_test() {
+ iterator.range(0, 10)
+ |> iterator.find(fn(e) { e == 5 })
+ |> should.equal(Ok(5))
+
+ iterator.range(0, 10)
+ |> iterator.find(fn(e) { e > 10 })
+ |> should.equal(Error(Nil))
+
+ iterator.empty()
+ |> iterator.find(fn(_x) { True })
+ |> should.equal(Error(Nil))
+
+ iterator.unfold(
+ Cat(id: 1),
+ fn(cat: Cat) { iterator.Next(cat, Cat(id: cat.id + 1)) },
+ )
+ |> iterator.find(fn(cat: Cat) { cat.id == 10 })
+ |> should.equal(Ok(Cat(id: 10)))
+}
- pub fn take_while_test() {
- iterator.from_list([1, 2, 3, 2, 4])
- |> iterator.take_while(satisfying: fn(x) { x < 3 })
- |> iterator.to_list
- |> should.equal([1, 2])
- }
+pub fn index_test() {
+ iterator.from_list(["a", "b", "c"])
+ |> iterator.index
+ |> iterator.to_list
+ |> should.equal([#(0, "a"), #(1, "b"), #(2, "c")])
+}
- pub fn drop_while_test() {
- iterator.from_list([1, 2, 3, 4, 2, 5])
- |> iterator.drop_while(satisfying: fn(x) { x < 4 })
- |> iterator.to_list
- |> should.equal([4, 2, 5])
- }
+pub fn iterate_test() {
+ fn(x) { x * 3 }
+ |> iterator.iterate(from: 1)
+ |> iterator.take(5)
+ |> iterator.to_list
+ |> should.equal([1, 3, 9, 27, 81])
+}
- pub fn scan_test() {
- iterator.from_list([1, 2, 3, 4, 5])
- |> iterator.scan(from: 0, with: fn(el, acc) { acc + el })
- |> iterator.to_list
- |> should.equal([1, 3, 6, 10, 15])
- }
+pub fn take_while_test() {
+ iterator.from_list([1, 2, 3, 2, 4])
+ |> iterator.take_while(satisfying: fn(x) { x < 3 })
+ |> iterator.to_list
+ |> should.equal([1, 2])
+}
- pub fn zip_test() {
- iterator.from_list(["a", "b", "c"])
- |> iterator.zip(iterator.range(20, 30))
- |> iterator.to_list
- |> should.equal([#("a", 20), #("b", 21), #("c", 22)])
- }
+pub fn drop_while_test() {
+ iterator.from_list([1, 2, 3, 4, 2, 5])
+ |> iterator.drop_while(satisfying: fn(x) { x < 4 })
+ |> iterator.to_list
+ |> should.equal([4, 2, 5])
+}
- pub fn chunk_test() {
- iterator.from_list([1, 2, 2, 3, 4, 4, 6, 7, 7])
- |> iterator.chunk(by: fn(n) { n % 2 })
- |> iterator.to_list
- |> should.equal([[1], [2, 2], [3], [4, 4, 6], [7, 7]])
- }
+pub fn scan_test() {
+ iterator.from_list([1, 2, 3, 4, 5])
+ |> iterator.scan(from: 0, with: fn(el, acc) { acc + el })
+ |> iterator.to_list
+ |> should.equal([1, 3, 6, 10, 15])
+}
- pub fn sized_chunk_test() {
- iterator.from_list([1, 2, 3, 4, 5, 6])
- |> iterator.sized_chunk(into: 2)
- |> iterator.to_list
- |> should.equal([[1, 2], [3, 4], [5, 6]])
+pub fn zip_test() {
+ iterator.from_list(["a", "b", "c"])
+ |> iterator.zip(iterator.range(20, 30))
+ |> iterator.to_list
+ |> should.equal([#("a", 20), #("b", 21), #("c", 22)])
+}
- iterator.from_list([1, 2, 3, 4, 5, 6, 7, 8])
- |> iterator.sized_chunk(into: 3)
- |> iterator.to_list
- |> should.equal([[1, 2, 3], [4, 5, 6], [7, 8]])
- }
+pub fn chunk_test() {
+ iterator.from_list([1, 2, 2, 3, 4, 4, 6, 7, 7])
+ |> iterator.chunk(by: fn(n) { n % 2 })
+ |> iterator.to_list
+ |> should.equal([[1], [2, 2], [3], [4, 4, 6], [7, 7]])
+}
- pub fn intersperse_test() {
- iterator.empty()
- |> iterator.intersperse(with: 0)
- |> iterator.to_list
- |> should.equal([])
+pub fn sized_chunk_test() {
+ iterator.from_list([1, 2, 3, 4, 5, 6])
+ |> iterator.sized_chunk(into: 2)
+ |> iterator.to_list
+ |> should.equal([[1, 2], [3, 4], [5, 6]])
- iterator.from_list([1])
- |> iterator.intersperse(with: 0)
- |> iterator.to_list
- |> should.equal([1])
+ iterator.from_list([1, 2, 3, 4, 5, 6, 7, 8])
+ |> iterator.sized_chunk(into: 3)
+ |> iterator.to_list
+ |> should.equal([[1, 2, 3], [4, 5, 6], [7, 8]])
+}
- iterator.from_list([1, 2, 3, 4, 5])
- |> iterator.intersperse(with: 0)
- |> iterator.to_list
- |> should.equal([1, 0, 2, 0, 3, 0, 4, 0, 5])
- }
+pub fn intersperse_test() {
+ iterator.empty()
+ |> iterator.intersperse(with: 0)
+ |> iterator.to_list
+ |> should.equal([])
+
+ iterator.from_list([1])
+ |> iterator.intersperse(with: 0)
+ |> iterator.to_list
+ |> should.equal([1])
+
+ iterator.from_list([1, 2, 3, 4, 5])
+ |> iterator.intersperse(with: 0)
+ |> iterator.to_list
+ |> should.equal([1, 0, 2, 0, 3, 0, 4, 0, 5])
+}
- pub fn any_test() {
- iterator.empty()
- |> iterator.any(satisfying: fn(n) { n % 2 == 0 })
- |> should.be_false
+pub fn any_test() {
+ iterator.empty()
+ |> iterator.any(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_false
- iterator.from_list([1, 2, 5, 7, 9])
- |> iterator.any(satisfying: fn(n) { n % 2 == 0 })
- |> should.be_true
+ iterator.from_list([1, 2, 5, 7, 9])
+ |> iterator.any(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_true
- iterator.from_list([1, 3, 5, 7, 9])
- |> iterator.any(satisfying: fn(n) { n % 2 == 0 })
- |> should.be_false
- }
+ iterator.from_list([1, 3, 5, 7, 9])
+ |> iterator.any(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_false
+}
- pub fn all_test() {
- iterator.empty()
- |> iterator.all(satisfying: fn(n) { n % 2 == 0 })
- |> should.be_true
+pub fn all_test() {
+ iterator.empty()
+ |> iterator.all(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_true
- iterator.from_list([2, 4, 6, 8])
- |> iterator.all(satisfying: fn(n) { n % 2 == 0 })
- |> should.be_true
+ iterator.from_list([2, 4, 6, 8])
+ |> iterator.all(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_true
- iterator.from_list([2, 4, 5, 8])
- |> iterator.all(satisfying: fn(n) { n % 2 == 0 })
- |> should.be_false
- }
+ iterator.from_list([2, 4, 5, 8])
+ |> iterator.all(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_false
+}
+if erlang {
pub fn group_test() {
iterator.from_list([1, 2, 3, 4, 5, 6])
|> iterator.group(by: fn(n) { n % 3 })
@@ -380,70 +388,70 @@ if erlang {
|> iterator.reduce(with: fn(x, y) { x + y })
|> should.equal(Ok(15))
}
+}
- pub fn last_test() {
- iterator.empty()
- |> iterator.last
- |> should.equal(Error(Nil))
+pub fn last_test() {
+ iterator.empty()
+ |> iterator.last
+ |> should.equal(Error(Nil))
- iterator.range(1, 10)
- |> iterator.last
- |> should.equal(Ok(9))
- }
+ iterator.range(1, 10)
+ |> iterator.last
+ |> should.equal(Ok(9))
+}
- pub fn empty_test() {
- iterator.empty()
- |> iterator.to_list
- |> should.equal([])
- }
+pub fn empty_test() {
+ iterator.empty()
+ |> iterator.to_list
+ |> should.equal([])
+}
- pub fn once_test() {
- iterator.once(fn() { 1 })
- |> iterator.to_list
- |> should.equal([1])
- }
+pub fn once_test() {
+ iterator.once(fn() { 1 })
+ |> iterator.to_list
+ |> should.equal([1])
+}
- pub fn single_test() {
- iterator.single(1)
- |> iterator.to_list
- |> should.equal([1])
- }
+pub fn single_test() {
+ iterator.single(1)
+ |> iterator.to_list
+ |> should.equal([1])
+}
- pub fn interleave_test() {
- iterator.from_list([1, 2, 3, 4])
- |> iterator.interleave(with: iterator.from_list([11, 12, 13, 14]))
- |> iterator.to_list
- |> should.equal([1, 11, 2, 12, 3, 13, 4, 14])
+pub fn interleave_test() {
+ iterator.from_list([1, 2, 3, 4])
+ |> iterator.interleave(with: iterator.from_list([11, 12, 13, 14]))
+ |> iterator.to_list
+ |> should.equal([1, 11, 2, 12, 3, 13, 4, 14])
- iterator.from_list([1, 2, 3, 4])
- |> iterator.interleave(with: iterator.from_list([100]))
- |> iterator.to_list
- |> should.equal([1, 100, 2, 3, 4])
- }
+ iterator.from_list([1, 2, 3, 4])
+ |> iterator.interleave(with: iterator.from_list([100]))
+ |> iterator.to_list
+ |> should.equal([1, 100, 2, 3, 4])
+}
- // a |> from_list |> fold_until(a, f) == a |> list.fold_until(_, a, f)
- pub fn fold_until_test() {
- let test = fn(subject, acc, f) {
- subject
- |> iterator.from_list()
- |> iterator.fold_until(acc, f)
- |> should.equal(list.fold_until(subject, acc, f))
- }
+// a |> from_list |> fold_until(a, f) == a |> list.fold_until(_, a, f)
+pub fn fold_until_test() {
+ let test = fn(subject, acc, f) {
+ subject
+ |> iterator.from_list()
+ |> iterator.fold_until(acc, f)
+ |> should.equal(list.fold_until(subject, acc, f))
+ }
- let f = fn(e, acc) {
- case e {
- _ if e < 6 -> list.Continue([e, ..acc])
- _ -> list.Stop(acc)
- }
+ let f = fn(e, acc) {
+ case e {
+ _ if e < 6 -> list.Continue([e, ..acc])
+ _ -> list.Stop(acc)
}
- test([], [], f)
- test([1], [], f)
- test([1, 2, 3], [], f)
- test([1, 2, 3, 4, 5, 6, 7, 8], [], f)
-
- [1, 2, 3, 4, 5, 6, 7, 8]
- |> iterator.from_list()
- |> iterator.fold_until([], f)
- |> should.equal([5, 4, 3, 2, 1])
}
+ test([], [], f)
+ test([1], [], f)
+ test([1, 2, 3], [], f)
+ test([1, 2, 3, 4, 5, 6, 7, 8], [], f)
+
+ [1, 2, 3, 4, 5, 6, 7, 8]
+ |> iterator.from_list()
+ |> iterator.fold_until([], f)
+ |> should.equal([5, 4, 3, 2, 1])
}
diff --git a/test/gleam/string_test.gleam b/test/gleam/string_test.gleam
index 734d369..8ac6d9c 100644
--- a/test/gleam/string_test.gleam
+++ b/test/gleam/string_test.gleam
@@ -272,8 +272,16 @@ pub fn pad_left_test() {
|> should.equal("121")
"121"
+ |> string.pad_left(to: 4, with: "XY")
+ |> should.equal("X121")
+
+ "121"
|> string.pad_left(to: 5, with: "XY")
- |> should.equal("XYXY121")
+ |> should.equal("XY121")
+
+ "121"
+ |> string.pad_left(to: 6, with: "XY")
+ |> should.equal("XYX121")
}
pub fn pad_right_test() {
@@ -290,8 +298,16 @@ pub fn pad_right_test() {
|> should.equal("121")
"121"
+ |> string.pad_right(to: 4, with: "XY")
+ |> should.equal("121X")
+
+ "121"
|> string.pad_right(to: 5, with: "XY")
- |> should.equal("121XYXY")
+ |> should.equal("121XY")
+
+ "121"
+ |> string.pad_right(to: 6, with: "XY")
+ |> should.equal("121XYX")
}
pub fn pop_grapheme_test() {