Skip to content

Commit ecdfc28

Browse files
committed
wip add main test
Signed-off-by: James Hamlin <jfhamlin@gmail.com>
1 parent e4feff4 commit ecdfc28

4 files changed

Lines changed: 173 additions & 20 deletions

File tree

pkg/codegen/codegen_test.go

Lines changed: 150 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,97 @@ import (
2020

2121
var updateGolden = flag.Bool("update", false, "update golden files")
2222

23+
const testHarnessCode = `package main
24+
25+
import (
26+
"fmt"
27+
"io/ioutil"
28+
"os"
29+
"path/filepath"
30+
"strings"
31+
32+
_ "github.com/glojurelang/glojure/pkg/codegen/testdata/codegen/test"
33+
"github.com/glojurelang/glojure/pkg/lang"
34+
)
35+
36+
func main() {
37+
// Find all .glj files in testdata directory
38+
// Get the testdata path relative to GOPATH or module root
39+
testdataDir := os.Args[1]
40+
var namespaces []string
41+
42+
err := filepath.Walk(testdataDir, func(path string, info os.FileInfo, err error) error {
43+
if err != nil {
44+
return err
45+
}
46+
if strings.HasSuffix(path, ".glj") {
47+
// Read first line to get namespace
48+
content, err := ioutil.ReadFile(path)
49+
if err != nil {
50+
return err
51+
}
52+
lines := strings.Split(string(content), "\n")
53+
if len(lines) > 0 && strings.HasPrefix(lines[0], "(ns ") {
54+
// Extract namespace name
55+
nsLine := lines[0]
56+
nsLine = strings.TrimPrefix(nsLine, "(ns ")
57+
nsLine = strings.TrimSuffix(nsLine, ")")
58+
parts := strings.Fields(nsLine)
59+
if len(parts) > 0 {
60+
namespaces = append(namespaces, parts[0])
61+
}
62+
}
63+
}
64+
return nil
65+
})
66+
if err != nil {
67+
fmt.Printf("Error walking testdata: %v\n", err)
68+
os.Exit(1)
69+
}
70+
71+
failed := false
72+
for _, nsName := range namespaces {
73+
ns := lang.FindNamespace(lang.NewSymbol(nsName))
74+
if ns == nil {
75+
fmt.Printf("SKIP: namespace %s not found\n", nsName)
76+
continue
77+
}
78+
79+
mainVar := ns.FindInternedVar(lang.NewSymbol("-main"))
80+
if mainVar == nil {
81+
fmt.Printf("SKIP: %s/-main not found\n", nsName)
82+
continue
83+
}
84+
85+
// Check if -main has :expected-output metadata
86+
meta := mainVar.Meta()
87+
if meta == nil {
88+
fmt.Printf("SKIP: %s/-main has no metadata\n", nsName)
89+
continue
90+
}
91+
92+
expected := meta.ValAt(lang.NewKeyword("expected-output"))
93+
if expected == nil {
94+
fmt.Printf("SKIP: %s/-main has no :expected-output\n", nsName)
95+
continue
96+
}
97+
98+
// Run -main and check the result
99+
result := mainVar.Invoke()
100+
if !lang.Equals(result, expected) {
101+
fmt.Printf("FAIL: %s/-main returned %v, expected %v\n", nsName, result, expected)
102+
failed = true
103+
} else {
104+
fmt.Printf("PASS: %s/-main\n", nsName)
105+
}
106+
}
107+
108+
if failed {
109+
os.Exit(1)
110+
}
111+
}
112+
`
113+
23114
func TestCodegen(t *testing.T) {
24115
var testFiles []string
25116
err := filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error {
@@ -93,8 +184,8 @@ func TestCodegen(t *testing.T) {
93184
t.Errorf("go vet failed for %s: %v\nStderr:\n%s", goldenFile, err, stderr.String())
94185
}
95186

96-
// TODO: Compile and run the generated code to verify behavior
97-
// This will be added once we have more complete code generation
187+
// Check if namespace has -main function with expected output
188+
testMainFunction(t, ns)
98189
})
99190
}
100191
}
@@ -131,8 +222,61 @@ func getNamespaceFromFile(t *testing.T, filename string) string {
131222
panic("expected namespace declaration in " + filename)
132223
}
133224

134-
// TestBehavior verifies that generated code produces the same results as interpreted code
135-
func TestBehavior(t *testing.T) {
136-
// This test will be implemented once we can compile and run generated code
137-
t.Skip("Behavioral testing not yet implemented")
225+
// testMainFunction tests the -main function if it exists and has :expected-output metadata
226+
func testMainFunction(t *testing.T, ns *lang.Namespace) {
227+
// Look for -main var in the namespace
228+
mainVar := ns.FindInternedVar(lang.NewSymbol("-main"))
229+
if mainVar == nil {
230+
// No -main function, nothing to test
231+
return
232+
}
233+
234+
// Check if -main has :expected-output metadata
235+
meta := mainVar.Meta()
236+
if meta == nil {
237+
return
238+
}
239+
240+
expectedOutput := meta.ValAt(lang.NewKeyword("expected-output"))
241+
if expectedOutput == nil {
242+
return
243+
}
244+
245+
// Run -main and check the result
246+
result := mainVar.Invoke()
247+
if !lang.Equals(result, expectedOutput) {
248+
t.Errorf("-main returned %v, expected %v", result, expectedOutput)
249+
}
250+
}
251+
252+
// TestGeneratedCode compiles and runs the generated code to verify behavior
253+
func TestGeneratedCode(t *testing.T) {
254+
// Write the test harness in a temporary directory
255+
tmpDir, err := ioutil.TempDir("", "glojure_test_harness")
256+
if err != nil {
257+
t.Fatal(err)
258+
}
259+
defer os.RemoveAll(tmpDir)
260+
261+
harnessPath := filepath.Join(tmpDir, "harness_main.go")
262+
if err := ioutil.WriteFile(harnessPath, []byte(testHarnessCode), 0644); err != nil {
263+
t.Fatal(err)
264+
}
265+
266+
// Get absolute path to testdata directory
267+
testdataPath, err := filepath.Abs("testdata")
268+
if err != nil {
269+
t.Fatal(err)
270+
}
271+
272+
// Compile and run the test harness
273+
cmd := exec.Command("go", "run", harnessPath, testdataPath)
274+
cmd.Dir = "."
275+
output, err := cmd.CombinedOutput()
276+
if err != nil {
277+
t.Fatalf("Test harness failed: %v\nOutput:\n%s", err, output)
278+
}
279+
280+
// Print the output for visibility
281+
t.Logf("Test harness output:\n%s", output)
138282
}

pkg/codegen/testdata/codegen/test/loop_simple.glj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@
55
(if (< i 10)
66
(recur (inc i))
77
i)))
8+
9+
(defn ^{:expected-output 10}
10+
-main [] (simple-loop))

pkg/codegen/testdata/codegen/test/loop_simple.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/codegen/testdata/codegen/test/main/main.go

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)