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.
181 lines
3.6 KiB
Go
181 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('Hello, World!');"
|
|
run(source)
|
|
|
|
// back to normal state
|
|
w.Close()
|
|
os.Stdout = old // restoring the real stdout
|
|
out := <-outC
|
|
|
|
// reading our temp stdout
|
|
expected := source + "\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('Hello, World!');"
|
|
if _, err := tmpfile.Write([]byte(content)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := tmpfile.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
RunFile(tmpfile.Name())
|
|
|
|
// back to normal state
|
|
w.Close()
|
|
os.Stdout = old // restoring the real stdout
|
|
out := <-outC
|
|
|
|
// reading our temp stdout
|
|
expected := "print('Hello, World!');\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."
|
|
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."
|
|
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('Hello, World!');\n\n"
|
|
wIn.Write([]byte(input))
|
|
wIn.Close()
|
|
|
|
RunPrompt()
|
|
|
|
wOut.Close()
|
|
os.Stdin = oldStdin
|
|
os.Stdout = oldStdout
|
|
out := <-outC
|
|
|
|
expected := "> print('Hello, World!');\n\n> "
|
|
if out != expected {
|
|
t.Errorf("RunPrompt() = %v; want %v", out, expected)
|
|
}
|
|
}
|