diff --git a/import.go b/import.go index 133f9d25d..86c3121e8 100644 --- a/import.go +++ b/import.go @@ -2,7 +2,11 @@ package main import "strings" -var Imports = []string{"fmt"} +var Imports []string + +func init() { + initImports() +} func addImport(importName string) { for _, i := range Imports { @@ -25,3 +29,7 @@ func importType(typeName string) string { return typeName } + +func initImports() { + Imports = []string{"fmt"} +} diff --git a/main.go b/main.go index 5a4e5f72b..e0c663081 100644 --- a/main.go +++ b/main.go @@ -174,6 +174,9 @@ func Start(args []string) string { all += ")\n\n" + go_out.String() + // Reset the imports + initImports() + return all } diff --git a/main_test.go b/main_test.go index 433d536aa..986b7c173 100644 --- a/main_test.go +++ b/main_test.go @@ -1,22 +1,87 @@ package main import ( + "bytes" + "io/ioutil" + "os" + "os/exec" "path/filepath" + "strings" "testing" ) -// This test exists for code coverage and does not actually test anything. The -// real tests are performed with run-tests.h. -// -// In the future it would be nice to combine them so that the files only have to -// be compiled once and we don't need the extra bash script. +var ( + cPath = "build/a.out" + goPath = "build/go.out" + stdin = "7" + args = []string{"some", "args"} +) + +type programOut struct { + stdout bytes.Buffer + stderr bytes.Buffer + isZero bool +} + +// TestIntegrationScripts tests all programs in the tests directory func TestIntegrationScripts(t *testing.T) { files, err := filepath.Glob("tests/*/*.c") if err != nil { - panic(err) + t.Fatal(err) } for _, file := range files { - Start([]string{file}) + // Create build folder + os.Mkdir("build/", os.ModePerm) + + t.Run(file, func(t *testing.T) { + cProgram := programOut{} + goProgram := programOut{} + + // Compile C + err := exec.Command("clang", "-lm", "-o", cPath, file).Run() + if err != nil { + t.Fatal(err) + } + + // Run C program + cmd := exec.Command(cPath, args...) + cmd.Stdin = strings.NewReader(stdin) + cmd.Stdout = &cProgram.stdout + cmd.Stderr = &cProgram.stderr + err = cmd.Run() + cProgram.isZero = err == nil + + // Compile Go + goSrc := Start([]string{file}) + ioutil.WriteFile("build/main.go", []byte(goSrc), os.ModePerm) + err = exec.Command("go", "build", "-o", goPath, "build/main.go").Run() + if err != nil { + t.Fatal(err) + } + + // Run Go program + cmd = exec.Command(goPath, args...) + cmd.Stdin = strings.NewReader(stdin) + cmd.Stdout = &goProgram.stdout + cmd.Stderr = &goProgram.stderr + err = cmd.Run() + goProgram.isZero = err == nil + + // Check if both exit codes are zero (or non-zero) + if cProgram.isZero != goProgram.isZero { + t.Fatalf("Expected: %t, Got: %t", cProgram.isZero, goProgram.isZero) + } + + // Check stderr + if cProgram.stderr.String() != goProgram.stderr.String() { + t.Fatalf("Expected %q, Got: %q", cProgram.stderr.String(), goProgram.stderr.String()) + } + + // Check stdout + if cProgram.stdout.String() != goProgram.stdout.String() { + t.Fatalf("Expected %q, Got: %q", cProgram.stdout.String(), goProgram.stdout.String()) + } + }) } } diff --git a/run-tests.sh b/run-tests.sh deleted file mode 100755 index 2cafb1a44..000000000 --- a/run-tests.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash - -CLANG_BIN=${CLANG_BIN:-clang} -CLANG_VERSION=$($CLANG_BIN --version) - -echo "CLANG_BIN=$CLANG_BIN" -echo "CLANG_VERSION=$CLANG_VERSION" -echo - -function run_test { - export TEST=$1 - - echo $TEST - - # Compile with clang. - $CLANG_BIN -lm $TEST - if [ $? != 0 ]; then - exit 1 - fi - - # Run the program in a subshell so that the "Abort trap: 6" message is not - # printed. - $(echo "7" | ./a.out some args 2> /tmp/1-stderr.txt 1> /tmp/1-stdout.txt) - C_EXIT_CODE=$? - - mkdir -p build - ./c2go $TEST > build/main.go - cd build && go build && cd .. - - if [ $? != 0 ]; then - echo "=== out.go" - cat --number build/main.go - exit 1 - fi - - # Run the program in a subshell so that the "Abort trap: 6" message is not - # printed. - $(echo "7" | ./build/build some args 2> /tmp/2-stderr.txt 1> /tmp/2-stdout.txt) - GO_EXIT_CODE=$? - - if [ $C_EXIT_CODE -ne $GO_EXIT_CODE ]; then - echo "ERROR: Received exit code $GO_EXIT_CODE from Go, but expected $C_EXIT_CODE." - exit 1 - fi - - # Compare the output of the stdout and stderr from C and Go. - diff /tmp/1-stderr.txt /tmp/2-stderr.txt - diff /tmp/1-stdout.txt /tmp/2-stdout.txt -} - -# Before we begin, lets build c2go -go build - -for TEST in ${@-$(find tests -name "*.c")}; do - run_test $TEST -done