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 with5
// purrc, runs it under the cheatah runtime, and asserts the exact stdout. Complements6
// the in-process unit tests (stdlib/tests/io_test.cpp) and the per-module7
// system-level test (StdlibE2E.Io).8
//9
// File I/O tests write to a unique path under /tmp from inside the .purr program, then10
// read it back and io.print the content, so each test is self-contained and11
// deterministic. io.input is intentionally NOT covered here: it reads from stdin, which12
// the e2e harness does not feed (it is covered by the in-process test13
// CheatahIo.InputReadsALine instead).14
#include "e2e_harness.hpp"16
TEST(IoCompileRun, Str) {17
e2e::expect_e2e("io_str", R"PURR(import io18
io.print(io.str(42))19
)PURR", "42\n");20
}22
TEST(IoCompileRun, Repr) {23
e2e::expect_e2e("io_repr", R"PURR(import io24
io.print(io.repr("hi"))25
)PURR", "'hi'\n");26
}28
TEST(IoCompileRun, Print) {29
e2e::expect_e2e("io_print", R"PURR(import io30
io.print("meow", 42, "purr")31
)PURR", "meow 42 purr\n");32
}34
// io.print renders a struct PRETTY (nice + readable by default): on multiple indented lines.35
TEST(IoCompileRun, PrintPrettyStruct) {36
e2e::expect_e2e("io_print_pretty", R"PURR(import io37
struct Point {38
x: float39
y: float40
}41
let p = Point({.x = 1, .y = 2})42
io.print(p)43
)PURR",44
"Point(\n x = 1,\n y = 2\n)\n");45
}47
// io.rprint prints a struct RAW — its compact `Name(field=value, …)` form, exactly as stored.48
TEST(IoCompileRun, Rprint) {49
e2e::expect_e2e("io_rprint", R"PURR(import io50
struct Point {51
x: float52
y: float53
}54
let p = Point({.x = 1, .y = 2})55
io.rprint(p)56
)PURR",57
"Point(x=1, y=2)\n");58
}60
// Nested structs pretty-print recursively, each level indented under its parent.61
TEST(IoCompileRun, PrintPrettyNestedStruct) {62
e2e::expect_e2e("io_print_pretty_nested", R"PURR(import io63
struct Inner { a: float }64
struct Outer {65
inner: Inner66
b: float67
}68
let o = Outer({.inner = Inner({.a = 5}), .b = 7})69
io.print(o)70
)PURR",71
"Outer(\n inner = Inner(\n a = 5\n ),\n b = 7\n)\n");72
}74
TEST(IoCompileRun, Format) {75
e2e::expect_e2e("io_format", R"PURR(import io76
io.print(io.format("{} ate {} fish", "cat", 3))77
)PURR", "cat ate 3 fish\n");78
}80
TEST(IoCompileRun, Fixed) {81
e2e::expect_e2e("io_fixed", R"PURR(import io82
io.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");84
}86
TEST(IoCompileRun, OpenWriteRead) {87
e2e::expect_e2e("io_open", R"PURR(import io88
let f = io.open("/tmp/cr_io_open.txt", "w")89
f.write("meow\npurr\n")90
f.close()91
let g = io.open("/tmp/cr_io_open.txt", "r")92
io.print(g.read())93
g.close()94
)PURR", "meow\npurr\n\n");95
}97
TEST(IoCompileRun, Readline) {98
e2e::expect_e2e("io_readline", R"PURR(import io99
let f = io.open("/tmp/cr_io_readline.txt", "w")100
f.write("meow\npurr\nnap\n")101
f.close()102
let g = io.open("/tmp/cr_io_readline.txt", "r")103
io.print(g.readline())104
io.print(g.readline())105
g.close()106
)PURR", "meow\npurr\n");107
}109
TEST(IoCompileRun, Readlines) {110
e2e::expect_e2e("io_readlines", R"PURR(import io111
let f = io.open("/tmp/cr_io_readlines.txt", "w")112
f.write("meow\npurr\nnap\n")113
f.close()114
let g = io.open("/tmp/cr_io_readlines.txt", "r")115
let lines = g.readlines()116
g.close()117
for line in lines { io.print(line) }118
)PURR", "meow\npurr\nnap\n");119
}121
TEST(IoCompileRun, IsOpenAndClose) {122
e2e::expect_e2e("io_is_open", R"PURR(import io123
let f = io.open("/tmp/cr_io_isopen.txt", "w")124
io.print(f.is_open())125
f.write("x")126
f.close()127
io.print(f.is_open())128
)PURR", "True\nFalse\n");129
}131
TEST(IoCompileRun, ReadFile) {132
e2e::expect_e2e("io_read_file", R"PURR(import io133
let f = io.open("/tmp/cr_io_readfile.txt", "w")134
f.write("meow\npurr\n")135
f.close()136
io.print(io.read_file("/tmp/cr_io_readfile.txt"))137
)PURR", "meow\npurr\n\n");138
}