import gleam/int import gleam/list import gleeunit import gleeunit/should import infiniyield.{Next} pub fn main() { gleeunit.main() } pub fn step_test() { let testcase = fn(subject) { let step = subject |> infiniyield.cycle |> infiniyield.step let assert [h, ..t] = subject let Next(h2, t2) = step h |> should.equal(h2) t2 |> infiniyield.take(list.length(t)) |> should.equal(t) } testcase([1]) testcase([1, 2]) testcase([1, 2, 3]) } // a |> cycle |> take(n) == a |> list.take(_, n) pub fn take_test() { let testcase = fn(n, subject) { subject |> infiniyield.cycle |> infiniyield.take(n) |> should.equal(list.take(subject, n)) } testcase(0, []) testcase(-1, []) testcase(0, [0]) testcase(1, [0]) testcase(-1, [0]) testcase(0, [0, 1, 2, 3, 4]) testcase(1, [0, 1, 2, 3, 4]) testcase(2, [0, 1, 2, 3, 4]) } pub fn transform_index_test() { let f = fn(i, el) { Next(#(i, el), i + 1) } ["a", "b", "c", "d"] |> infiniyield.cycle |> infiniyield.transform(0, f) |> infiniyield.take(4) |> should.equal([#(0, "a"), #(1, "b"), #(2, "c"), #(3, "d")]) } pub fn transform_scan_test() { let f = fn(acc, el) { let result = acc + el Next(result, result) } [1, 2, 3, 4, 5] |> infiniyield.cycle |> infiniyield.transform(0, f) |> infiniyield.take(5) |> should.equal([1, 3, 6, 10, 15]) } // a |> cycle |> map(f) == a |> list.map(_, f) pub fn map_test() { let testcase = fn(subject, f) { subject |> infiniyield.cycle |> infiniyield.map(f) |> infiniyield.take(list.length(subject)) |> should.equal(list.map(subject, f)) } let f = fn(e) { e * 2 } testcase([], f) testcase([1], f) testcase([1, 2, 3], f) testcase([1, 2, 3, 4, 5, 6, 7, 8], f) } // map2(cycle(a), cycle(b), f) == list.map2(a, b, f) pub fn map2_test() { let testcase = fn(one, other, f) { infiniyield.map2(infiniyield.cycle(one), infiniyield.cycle(other), f) |> infiniyield.take(int.min(list.length(one), list.length(other))) |> should.equal(list.map2(one, other, f)) } let f = fn(a, b) { a / b } testcase([], [], f) testcase([], [2, 10, 3], f) testcase([10], [2, 10, 3], f) testcase([10, 20], [2, 10, 3], f) testcase([10, 20, 30], [2, 10, 3], f) testcase([10, 20, 30], [2, 10], f) testcase([10, 20, 30], [2], f) testcase([10, 20, 30], [], f) } pub fn map2_is_lazy_test() { let one = infiniyield.cycle([]) let other = infiniyield.repeatedly(fn() { panic as "unreachable" }) infiniyield.map2(one, other, fn(x, y) { x + y }) |> infiniyield.take(0) |> should.equal([]) } // a |> cycle |> filter(f) == a |> list.filter(_, f) pub fn filter_test() { let testcase = fn(subject, f) { let lst = list.filter(subject, f) subject |> infiniyield.cycle |> infiniyield.filter(f) |> infiniyield.take(list.length(lst)) |> should.equal(lst) } let even = fn(x) { x % 2 == 0 } testcase([], even) testcase([1], even) testcase([1, 2], even) testcase([1, 2, 3], even) testcase([1, 2, 3, 4], even) testcase([1, 2, 3, 4, 5], even) testcase([1, 2, 3, 4, 5, 6], even) } pub fn filter_map_test() { let testcase = fn(subject, f) { let lst = list.filter_map(subject, f) subject |> infiniyield.cycle |> infiniyield.filter_map(f) |> infiniyield.take(list.length(lst)) |> should.equal(lst) } testcase([], int.parse) testcase(["1"], int.parse) testcase(["1", "2", "3"], int.parse) testcase(["1", "a", "b"], int.parse) testcase(["l", "2", "3", "a"], int.parse) testcase(["1", "c", "3", "a", "b"], int.parse) testcase(["1", "20", "ten", "4", "5", "69"], int.parse) } pub fn repeat_test() { 1 |> infiniyield.repeat |> infiniyield.take(5) |> should.equal([1, 1, 1, 1, 1]) } pub fn cycle_test() { [1, 2, 3] |> infiniyield.cycle |> infiniyield.take(9) |> should.equal([1, 2, 3, 1, 2, 3, 1, 2, 3]) } pub fn unfold_test() { infiniyield.unfold(2, fn(acc) { infiniyield.Next(acc, acc * 2) }) |> infiniyield.take(5) |> should.equal([2, 4, 8, 16, 32]) } pub fn incrementing_test() { let testcase = fn(a, expected) { infiniyield.incrementing(from: a) |> infiniyield.take(list.length(expected)) |> should.equal(expected) } testcase(0, [0]) testcase(1, [1]) testcase(-1, [-1]) testcase(0, [0, 1]) testcase(0, [0, 1, 2, 3, 4, 5]) testcase(1, [1, 2, 3, 4, 5]) } pub fn deccrementing_test() { let testcase = fn(a, expected) { infiniyield.decrementing(from: a) |> infiniyield.take(list.length(expected)) |> should.equal(expected) } testcase(0, [0]) testcase(1, [1]) testcase(-1, [-1]) testcase(0, [0, -1]) testcase(0, [0, -1, -2, -3, -4, -5]) testcase(1, [1, 0, -1, -2, -3, -4, -5]) } pub fn drop_test() { infiniyield.incrementing(from: 0) |> infiniyield.drop(5) |> infiniyield.take(6) |> should.equal([5, 6, 7, 8, 9, 10]) } type Cat { Cat(id: Int) } pub fn find_test() { infiniyield.incrementing(from: 0) |> infiniyield.find(fn(e) { e == 5 }) |> should.equal(5) infiniyield.incrementing(from: 0) |> infiniyield.find(fn(e) { e > 10 }) |> should.equal(11) infiniyield.unfold(Cat(id: 1), fn(cat: Cat) { infiniyield.Next(cat, Cat(id: cat.id + 1)) }) |> infiniyield.find(fn(cat: Cat) { cat.id == 10 }) |> should.equal(Cat(id: 10)) } pub fn find_map_test() { infiniyield.incrementing(from: 0) |> infiniyield.find_map(fn(e) { case e == 5 { True -> Ok(e) False -> Error(Nil) } }) |> should.equal(5) infiniyield.incrementing(from: 0) |> infiniyield.find_map(fn(e) { case e > 10 { True -> Ok(e) False -> Error(Nil) } }) |> should.equal(11) infiniyield.unfold(Cat(id: 1), fn(cat: Cat) { infiniyield.Next(cat, Cat(id: cat.id + 1)) }) |> infiniyield.find_map(fn(cat: Cat) { case cat.id == 10 { True -> Ok(cat) False -> Error(Nil) } }) |> should.equal(Cat(id: 10)) } pub fn index_test() { infiniyield.cycle(["a", "b", "c"]) |> infiniyield.index |> infiniyield.take(3) |> should.equal([#("a", 0), #("b", 1), #("c", 2)]) } pub fn iterate_test() { fn(x) { x * 3 } |> infiniyield.iterate(from: 1) |> infiniyield.take(5) |> should.equal([1, 3, 9, 27, 81]) } pub fn take_while_test() { infiniyield.cycle([1, 2, 3, 2, 4]) |> infiniyield.take_while(satisfying: fn(x) { x < 3 }) |> should.equal([1, 2]) } pub fn drop_while_test() { infiniyield.cycle([1, 2, 3, 4, 2, 5]) |> infiniyield.drop_while(satisfying: fn(x) { x < 4 }) |> infiniyield.take(3) |> should.equal([4, 2, 5]) } pub fn scan_test() { infiniyield.cycle([1, 2, 3, 4, 5]) |> infiniyield.scan(from: 0, with: fn(acc, el) { acc + el }) |> infiniyield.take(5) |> should.equal([1, 3, 6, 10, 15]) } pub fn zip_test() { infiniyield.cycle(["a", "b", "c"]) |> infiniyield.zip(infiniyield.incrementing(from: 20)) |> infiniyield.take(3) |> should.equal([#("a", 20), #("b", 21), #("c", 22)]) } pub fn chunk_test() { infiniyield.cycle([1, 2, 2, 3, 4, 4, 6, 7, 7]) |> infiniyield.chunk(by: fn(n) { n % 2 }) |> infiniyield.take(5) |> should.equal([[1], [2, 2], [3], [4, 4, 6], [7, 7, 1]]) } pub fn sized_chunk_test() { infiniyield.cycle([1, 2, 3, 4, 5, 6]) |> infiniyield.sized_chunk(into: 2) |> infiniyield.take(3) |> should.equal([[1, 2], [3, 4], [5, 6]]) infiniyield.cycle([1, 2, 3, 4, 5, 6, 7, 8]) |> infiniyield.sized_chunk(into: 3) |> infiniyield.take(3) |> should.equal([[1, 2, 3], [4, 5, 6], [7, 8, 1]]) } pub fn intersperse_test() { infiniyield.cycle([1]) |> infiniyield.intersperse(with: 0) |> infiniyield.take(1) |> should.equal([1]) infiniyield.cycle([1, 2, 3, 4, 5]) |> infiniyield.intersperse(with: 0) |> infiniyield.take(9) |> should.equal([1, 0, 2, 0, 3, 0, 4, 0, 5]) } pub fn interleave_test() { infiniyield.cycle([1, 2, 3, 4]) |> infiniyield.interleave(with: infiniyield.cycle([11, 12, 13, 14])) |> infiniyield.take(8) |> should.equal([1, 11, 2, 12, 3, 13, 4, 14]) infiniyield.cycle([1, 2, 3, 4]) |> infiniyield.interleave(with: infiniyield.cycle([100])) |> infiniyield.take(8) |> should.equal([1, 100, 2, 100, 3, 100, 4, 100]) } // a |> cycle |> fold_until(acc, f) == a |> list.fold_until(acc, f) pub fn fold_until_test() { let testcase = fn(subject, acc, f) { subject |> infiniyield.cycle() |> infiniyield.fold_until(acc, f) |> should.equal(list.fold_until(subject, acc, f)) } let f = fn(acc, e) { case e { _ if e < 6 -> list.Continue([e, ..acc]) _ -> list.Stop(acc) } } testcase([1, 2, 3, 4, 5, 6, 7, 8], [], f) [1, 2, 3, 4, 5, 6, 7, 8] |> infiniyield.cycle() |> infiniyield.fold_until([], f) |> should.equal([5, 4, 3, 2, 1]) } pub fn first_test() { infiniyield.cycle([1, 2, 3]) |> infiniyield.first |> should.equal(1) } pub fn at_test() { infiniyield.cycle([1, 2, 3, 4]) |> infiniyield.at(2) |> should.equal(3) infiniyield.cycle([1, 2, 3, 4]) |> infiniyield.at(4) |> should.equal(1) } pub fn each_test() { use it <- infiniyield.each(infiniyield.cycle([1])) it |> should.equal(1) } pub fn yield_test() { let items = { use <- infiniyield.yield(1) use <- infiniyield.yield(2) use <- infiniyield.yield(3) infiniyield.repeat(0) } items |> infiniyield.take(6) |> should.equal([1, 2, 3, 0, 0, 0]) } pub fn yield_computes_only_necessary_values_test() { let items = { use <- infiniyield.yield(1) use <- infiniyield.yield(2) use <- infiniyield.yield(3) panic as "yield computed more values than necessary" } items |> infiniyield.take(3) |> should.equal([1, 2, 3]) } pub fn prepend_test() { infiniyield.cycle([1, 2, 3]) |> infiniyield.prepend(0) |> infiniyield.take(4) |> should.equal([0, 1, 2, 3]) }