You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
3.6 KiB
Go

package lox
import (
"bytes"
"fmt"
"io"
"os"
"testing"
)
func TestRun(t *testing.T) {
old := os.Stdout // keep backup of the real stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stdout = w
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
source := "print 1+4/2;"
l := New()
l.run(source)
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
// reading our temp stdout
expected := "3\n"
if out != expected {
t.Errorf("run() = %v; want %v", out, expected)
}
}
func TestRunFile(t *testing.T) {
old := os.Stdout // keep backup of the real stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stdout = w
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
// Create a temporary file with some content
tmpfile, err := os.CreateTemp("", "example.*.txt")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpfile.Name())
content := "print 1+4/2;"
if _, err := tmpfile.Write([]byte(content)); err != nil {
t.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
t.Fatal(err)
}
l := New()
l.RunFile(tmpfile.Name())
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
// reading our temp stdout
expected := "3\n"
if out != expected {
t.Errorf("RunFile() = %v; want %v", out, expected)
}
}
func TestError(t *testing.T) {
old := os.Stdout // keep backup of the real stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stdout = w
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
line := 1
message := "Unexpected character."
l := New()
l.Error(line, message)
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
// reading our temp stdout
expected := fmt.Sprintf("[line %d] Error : %s\n", line, message)
if out != expected {
t.Errorf("Error() = %v; want %v", out, expected)
}
}
func TestReport(t *testing.T) {
old := os.Stdout // keep backup of the real stdout
r, w, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stdout = w
outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
line := 1
where := "at 'foo'"
message := "Unexpected character."
l := New()
l.report(line, where, message)
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
out := <-outC
// reading our temp stdout
expected := fmt.Sprintf("[line %d] Error %s: %s\n", line, where, message)
if out != expected {
t.Errorf("report() = %v; want %v", out, expected)
}
}
func TestRunPrompt(t *testing.T) {
oldStdin := os.Stdin
oldStdout := os.Stdout
rIn, wIn, _ := os.Pipe()
rOut, wOut, _ := os.Pipe()
os.Stdin = rIn
os.Stdout = wOut
outC := make(chan string)
go func() {
var buf bytes.Buffer
io.Copy(&buf, rOut)
outC <- buf.String()
}()
input := "print 1+4/2;\n\n"
wIn.Write([]byte(input))
wIn.Close()
l := New()
l.RunPrompt()
wOut.Close()
os.Stdin = oldStdin
os.Stdout = oldStdout
out := <-outC
expected := "> 3\n> "
if out != expected {
t.Errorf("RunPrompt() = %v; want %v", out, expected)
}
}