cheatah
Source

tests/purrc/io_cr_test.cpp

1// Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
2// Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
3// Compile-run unit tests for the `io` module: one test per purr-callable function.
4// Each writes a tiny .purr that exercises a single io entry point, compiles it with
5// purrc, runs it under the cheatah runtime, and asserts the exact stdout. Complements
6// the in-process unit tests (stdlib/tests/io_test.cpp) and the per-module
7// system-level test (StdlibE2E.Io).
8//
9// File I/O tests write to a unique path under /tmp from inside the .purr program, then
10// read it back and io.print the content, so each test is self-contained and
11// deterministic. io.input is intentionally NOT covered here: it reads from stdin, which
12// the e2e harness does not feed (it is covered by the in-process test
13// CheatahIo.InputReadsALine instead).
14#include "e2e_harness.hpp"
16TEST(IoCompileRun, Str) {
17 e2e::expect_e2e("io_str", R"PURR(import io
18io.print(io.str(42))
19)PURR", "42\n");
22TEST(IoCompileRun, Repr) {
23 e2e::expect_e2e("io_repr", R"PURR(import io
24io.print(io.repr("hi"))
25)PURR", "'hi'\n");
28TEST(IoCompileRun, Print) {
29 e2e::expect_e2e("io_print", R"PURR(import io
30io.print("meow", 42, "purr")
31)PURR", "meow 42 purr\n");
34// io.print renders a struct PRETTY (nice + readable by default): on multiple indented lines.
35TEST(IoCompileRun, PrintPrettyStruct) {
36 e2e::expect_e2e("io_print_pretty", R"PURR(import io
37struct Point {
38 x: float
39 y: float
41let p = Point({.x = 1, .y = 2})
42io.print(p)
43)PURR",
44 "Point(\n x = 1,\n y = 2\n)\n");
47// io.rprint prints a struct RAW — its compact `Name(field=value, …)` form, exactly as stored.
48TEST(IoCompileRun, Rprint) {
49 e2e::expect_e2e("io_rprint", R"PURR(import io
50struct Point {
51 x: float
52 y: float
54let p = Point({.x = 1, .y = 2})
55io.rprint(p)
56)PURR",
57 "Point(x=1, y=2)\n");
60// Nested structs pretty-print recursively, each level indented under its parent.
61TEST(IoCompileRun, PrintPrettyNestedStruct) {
62 e2e::expect_e2e("io_print_pretty_nested", R"PURR(import io
63struct Inner { a: float }
64struct Outer {
65 inner: Inner
66 b: float
68let o = Outer({.inner = Inner({.a = 5}), .b = 7})
69io.print(o)
70)PURR",
71 "Outer(\n inner = Inner(\n a = 5\n ),\n b = 7\n)\n");
74TEST(IoCompileRun, Format) {
75 e2e::expect_e2e("io_format", R"PURR(import io
76io.print(io.format("{} ate {} fish", "cat", 3))
77)PURR", "cat ate 3 fish\n");
80TEST(IoCompileRun, Fixed) {
81 e2e::expect_e2e("io_fixed", R"PURR(import io
82io.print(io.fixed(2.675, 2), io.fixed(12.0, 1), io.fixed(1.5, 0), io.fixed(-1.25, 1))
83)PURR", "2.67 12.0 2 -1.2\n");
86TEST(IoCompileRun, OpenWriteRead) {
87 e2e::expect_e2e("io_open", R"PURR(import io
88let f = io.open("/tmp/cr_io_open.txt", "w")
89f.write("meow\npurr\n")
90f.close()
91let g = io.open("/tmp/cr_io_open.txt", "r")
92io.print(g.read())
93g.close()
94)PURR", "meow\npurr\n\n");
97TEST(IoCompileRun, Readline) {
98 e2e::expect_e2e("io_readline", R"PURR(import io
99let f = io.open("/tmp/cr_io_readline.txt", "w")
100f.write("meow\npurr\nnap\n")
101f.close()
102let g = io.open("/tmp/cr_io_readline.txt", "r")
103io.print(g.readline())
104io.print(g.readline())
105g.close()
106)PURR", "meow\npurr\n");
109TEST(IoCompileRun, Readlines) {
110 e2e::expect_e2e("io_readlines", R"PURR(import io
111let f = io.open("/tmp/cr_io_readlines.txt", "w")
112f.write("meow\npurr\nnap\n")
113f.close()
114let g = io.open("/tmp/cr_io_readlines.txt", "r")
115let lines = g.readlines()
116g.close()
117for line in lines { io.print(line) }
118)PURR", "meow\npurr\nnap\n");
121TEST(IoCompileRun, IsOpenAndClose) {
122 e2e::expect_e2e("io_is_open", R"PURR(import io
123let f = io.open("/tmp/cr_io_isopen.txt", "w")
124io.print(f.is_open())
125f.write("x")
126f.close()
127io.print(f.is_open())
128)PURR", "True\nFalse\n");
131TEST(IoCompileRun, ReadFile) {
132 e2e::expect_e2e("io_read_file", R"PURR(import io
133let f = io.open("/tmp/cr_io_readfile.txt", "w")
134f.write("meow\npurr\n")
135f.close()
136io.print(io.read_file("/tmp/cr_io_readfile.txt"))
137)PURR", "meow\npurr\n\n");