-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmain_test.go
151 lines (138 loc) · 3.75 KB
/
main_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package main
import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
const testcaseDirectory = "testcases/"
var testPrograms = []string{
//"multiline_map",
"multiline_string",
"var_string",
"var_multi",
"string_args",
"defer",
"iota",
"map_struct",
"for_range_map_key_value",
"for_range_map_value",
"for_range_map_key",
"string_map",
"struct",
"var2",
"for_range_both",
"for_endless",
"for_range_single",
"for_range_list",
"for_regular",
"trimspace",
"printf",
"multiple",
"prefix",
"contains",
"if",
"var",
"output_char2",
"var_zero",
"output_char",
"const",
"continue",
"types",
"if_minus_one",
"goto",
"switch",
"hello",
"sprintf",
}
// Programs with unordered words as the output
var unorderedOutput = []string{
"string_map",
"for_range_map_key_value",
"for_range_map_value",
"for_range_map_key",
}
func assertEqual(t *testing.T, a interface{}, b interface{}, message string) {
if a == b {
return
}
if len(message) == 0 {
message = fmt.Sprintf("%v != %v", a, b)
}
t.Fatal(message)
}
// Run a command and return what has been written to stdout,
// or an empty string, and what has been written to stderr,
// or an empty string.
func Run(cmdString string) (string, string, error) {
var outputStdout, outputStderr bytes.Buffer
fields := strings.Split(cmdString, " ")
cmd := exec.Command(fields[0], fields[1:]...)
cmd.Stdout = &outputStdout
cmd.Stderr = &outputStderr
err := cmd.Run()
if err != nil {
return outputStdout.String(), outputStderr.String(), err
}
return outputStdout.String(), outputStderr.String(), nil
}
func exists(filename string) bool {
_, err := os.Stat(filename)
return err == nil
}
func TestPrograms(t *testing.T) {
Run("go build")
for _, program := range testPrograms {
gofile := filepath.Join(testcaseDirectory, program+".go")
if !exists(gofile) {
t.Fatal(gofile + " does not exist!")
}
// Program output when running with "go run"
fmt.Println("[go ] Compiling and running " + gofile + " (using go run)...")
stdoutGo, stderrGo, err := Run("go run " + gofile)
if err != nil {
t.Fatal(err)
}
// Program output when compiling with go2cpp and running the executable
fmt.Println("[ c++] Compiling and running " + gofile + " (using go2cpp and g++)...")
Run("./go2cpp " + gofile + " -o " + filepath.Join(testcaseDirectory, program))
stdoutTgc, stderrTgc, err := Run(filepath.Join(testcaseDirectory, program))
if err != nil {
cmd := "./go2cpp " + gofile + " -O"
if stdoutT, stderrT, err := Run(cmd); err != nil {
fmt.Println("TRANSPILATION FAILED:", cmd)
fmt.Println(stdoutT, stderrT)
} else {
t.Fatal("go2cpp should not first fail and then succeed! Something is wrong.")
}
fmt.Fprintln(os.Stderr, gofile)
t.Fatal(err)
}
Run("rm " + filepath.Join(testcaseDirectory, program))
// For some test-programs, assume the order of the outputted words are random
// And only check stdout.
if has(unorderedOutput, program) {
words1 := strings.Split(strings.TrimSpace(stdoutGo), " ")
words2 := strings.Split(strings.TrimSpace(stdoutTgc), " ")
for _, word := range words1 {
if !has(words2, word) {
fmt.Println(words2, "DOES NOT HAVE", word)
assertEqual(t, stdoutGo, stdoutTgc, "go2cpp and go run should produce the same list of words on stdout")
}
}
for _, word := range words2 {
if !has(words1, word) {
fmt.Println(words1, "DOES NOT HAVE", word)
assertEqual(t, stdoutGo, stdoutTgc, "go2cpp and go run should produce the same list of words on stdout")
}
}
continue
}
// Check if they are equal
assertEqual(t, stdoutGo, stdoutTgc, "go2cpp and go run should produce the same output on stdout")
assertEqual(t, stderrGo, stderrTgc, "go2cpp and go run should produce the same output on stderr")
}
}