import cs2030s.fp.InfiniteList; import cs2030s.fp.Immutator; import java.util.ArrayList; import java.util.List; class Test1 { public static void main(String[] args) { CS2030STest i = new CS2030STest(); i.expectReturn( "InfiniteList.generate(() -> 1).toString()", () -> InfiniteList.generate(() -> 1).toString(), "[? ?]"); i.expectReturn( "InfiniteList.generate(() -> 1).head()", () -> InfiniteList.generate(() -> 1).head(), 1); i.expectReturn( "InfiniteList.generate(() -> null).tail().head()", () -> InfiniteList.generate(() -> null).tail().head(), null); i.expectReturn( "InfiniteList.iterate(\"A\", x -> x + \"Z\").head()", () -> InfiniteList.iterate("A", x -> x + "Z").head(), "A"); i.expectReturn( "InfiniteList.iterate(\"A\", x -> x + \"Z\").tail().head()", () -> InfiniteList.iterate("A", x -> x + "Z").tail().head(), "AZ"); i.expectReturn( "InfiniteList.iterate(\"A\", x -> x + \"Z\").tail().tail().head()", () -> InfiniteList.iterate("A", x -> x + "Z").tail().tail().head(), "AZZ"); List evalHistory = new ArrayList<>(); Immutator op = x -> { evalHistory.add(x); return x + 1; }; InfiniteList numbers = InfiniteList.iterate(1, op); numbers.head(); i.expectReturn( "InfiniteList numbers = InfiniteList.iterate(1, x -> x + 1);\n" + "numbers.toString()", () -> numbers.toString(), "[<1> ?]"); i.expect("numbers.head() causes zero evaluation of x -> x + 1)", evalHistory, List.of()); i.expectReturn("numbers.toString())", () -> numbers.toString(), "[<1> ?]"); numbers.tail().head(); i.expect("numbers.tail().head() causes one evaluation of x -> x + 1", evalHistory, List.of(1)); i.expectReturn("numbers.toString())", () -> numbers.toString(), "[<1> [<2> ?]]"); numbers.tail().head(); i.expect("numbers.tail().head() (again) causes zero evaluation of x -> x + 1", evalHistory, List.of(1)); i.expectReturn("numbers.toString())", () -> numbers.toString(), "[<1> [<2> ?]]"); numbers.tail().tail().head(); i.expect("numbers.tail().tail().head() causes one evaluation of x -> x + 1", evalHistory, List.of(1, 2)); i.expectReturn("numbers.toString())", () -> numbers.toString(), "[<1> [<2> [<3> ?]]]"); numbers.tail().head(); i.expect("numbers.tail().head() (again) causes zero evaluation of x -> x + 1", evalHistory, List.of(1, 2)); i.expectReturn("numbers.toString())", () -> numbers.toString(), "[<1> [<2> [<3> ?]]]"); InfiniteList zeros = InfiniteList.generate(() -> { evalHistory.add(0); return 0; }); evalHistory.retainAll(List.of()); i.expect("InfiniteList zeros = InfiniteList.generate(() -> 0)\n" + "zeros.toString() returns [? ?]", () -> zeros.toString(), "[? ?]"); zeros.head(); i.expect("zeros.head() causes one evaluation of () -> 0", evalHistory, List.of(0)); i.expect("zeros.toString() returns [<0> ?]", () -> zeros.toString(), "[<0> ?]"); zeros.tail().head(); i.expect("zeros.tail().head() causes one evaluation of () -> 0)", evalHistory, List.of(0, 0)); i.expect("zeros.toString() returns [<0> [[0 ?]]]", () -> zeros.toString(), "[<0> [<0> ?]]"); zeros.head(); i.expect("zeros.head() (again) causes zero evaluation of () -> 0", evalHistory, List.of(0, 0)); i.expect("zeros.toString() returns [<0> [<0> ?]]", () -> zeros.toString(), "[<0> [<0> ?]]"); zeros.tail().head(); i.expect("zeros.tail().head() causes zero evaluation of () -> 0", evalHistory, List.of(0, 0)); i.expect("zeros.toString() returns [<0> [<0> ?]]", () -> zeros.toString(), "[<0> [<0> ?]]"); zeros.tail().tail().head(); i.expect("zeros.tail().tail().head() causes one more evaluation of () -> 0", evalHistory, List.of(0, 0, 0)); i.expect("zeros.toString() returns [<0> [<0> [<0> ?]]]", () -> zeros.toString(), "[<0> [<0> [<0> ?]]]"); zeros.tail().head(); i.expect("zeros.tail().head() (again) causes zero evaluation of () -> 0", evalHistory, List.of(0, 0, 0)); i.expect("zeros.toString() returns [<0> [<0> [<0> ?]]]", () -> zeros.toString(), "[<0> [<0> [<0> ?]]]"); } }