github.com/smasher164/tapl@v0.0.0-20230202055446-fd56bc413abd/tests/arith/all_test.go (about)

     1  package arith_test
     2  
     3  import (
     4  	"bytes"
     5  	"io/fs"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"strings"
    10  	"testing"
    11  )
    12  
    13  var (
    14  	testPath = func() string {
    15  		cwd, err := os.Getwd()
    16  		panicErr(err)
    17  		return cwd
    18  	}()
    19  	projectRoot = filepath.Dir(filepath.Dir(testPath))
    20  	testDir     = os.DirFS(testPath)
    21  	inOut       = func() map[string]string {
    22  		m := make(map[string]string)
    23  		panicErr(fs.WalkDir(testDir, ".", func(path string, d fs.DirEntry, err error) error {
    24  			parts := strings.Split(path, ".")
    25  			if len(parts) == 3 && parts[1] == "in" {
    26  				m[filepath.Join(testPath, path)] = strings.Join([]string{parts[0], "out.txt"}, ".")
    27  			}
    28  			return err
    29  		}))
    30  		return m
    31  	}()
    32  )
    33  
    34  func panicErr(err error) {
    35  	if err != nil {
    36  		panic(err)
    37  	}
    38  }
    39  
    40  func test(name string, args ...string) func(t *testing.T) {
    41  	return func(t *testing.T) {
    42  		for in, out := range inOut {
    43  			got, err := exec.Command(name, append(args, in)...).CombinedOutput()
    44  			if _, ok := err.(*exec.ExitError); !ok && err != nil {
    45  				t.Fatal(err)
    46  			}
    47  			want, err := fs.ReadFile(testDir, out)
    48  			if err != nil {
    49  				t.Fatal(err)
    50  			}
    51  			if bytes.Compare(got, want) != 0 {
    52  				t.Errorf("%s does not match output:\n`%s`", out, got)
    53  			}
    54  		}
    55  	}
    56  }
    57  
    58  func run(name string, args ...string) error {
    59  	cmd := exec.Command(name, args...)
    60  	cmd.Stderr = os.Stderr
    61  	return cmd.Run()
    62  }
    63  
    64  func TestGo(t *testing.T) {
    65  	if _, err := exec.LookPath("go"); err != nil {
    66  		t.Skip("could not find 'go' executable in PATH")
    67  	}
    68  	goDir := filepath.Join(projectRoot, "go", "arith")
    69  	os.Chdir(goDir)
    70  	if err := run("go", "build"); err != nil {
    71  		t.Fatal(err)
    72  	}
    73  	t.Run("SmallStep", test("./arith", "-small-step"))
    74  	t.Run("BigStep", test("./arith", "-big-step"))
    75  }
    76  
    77  func TestSML(t *testing.T) {
    78  	if _, err := exec.LookPath("mlton"); err != nil {
    79  		t.Skip("could not find 'mlton' executable in PATH")
    80  	}
    81  	smlDir := filepath.Join(projectRoot, "sml", "arith")
    82  	os.Chdir(smlDir)
    83  	if err := run(
    84  		"mlton",
    85  		"-default-ann", "allowExtendedTextConsts true",
    86  		"-default-ann", "allowOrPats true",
    87  		"arith.sml",
    88  	); err != nil {
    89  		t.Fatal(err)
    90  	}
    91  	t.Run("SmallStep", test("./arith", "-small-step"))
    92  	t.Run("BigStep", test("./arith", "-big-step"))
    93  }
    94  
    95  func TestC(t *testing.T) {
    96  	if _, err := exec.LookPath("cc"); err == nil {
    97  		cDir := filepath.Join(projectRoot, "c", "arith")
    98  		os.Chdir(cDir)
    99  		if err := run("cc", "-o", "arith", "arith.c"); err != nil {
   100  			t.Fatal(err)
   101  		}
   102  	} else if _, err := exec.LookPath("cl"); err == nil {
   103  		cDir := filepath.Join(projectRoot, "c", "arith")
   104  		os.Chdir(cDir)
   105  		if err := run("cl", "/std:c11", "/Fearith", "arith.c"); err != nil {
   106  			t.Fatal(err)
   107  		}
   108  	} else {
   109  		t.Skip("could not find 'cc' or 'cl' in PATH")
   110  	}
   111  	t.Run("SmallStep", test("./arith", "-small-step"))
   112  	t.Run("BigStep", test("./arith", "-big-step"))
   113  }
   114  
   115  func TestRust(t *testing.T) {
   116  	if _, err := exec.LookPath("cargo"); err != nil {
   117  		t.Skip("could not find 'cargo' executable in PATH")
   118  	}
   119  	rustDir := filepath.Join(projectRoot, "rust")
   120  	os.Chdir(rustDir)
   121  	if err := run("cargo", "build", "--quiet", "--release", "-p", "arith"); err != nil {
   122  		t.Fatal(err)
   123  	}
   124  	t.Run("SmallStep", test("./target/release/arith", "-small-step"))
   125  	t.Run("BigStep", test("./target/release/arith", "-big-step"))
   126  }
   127  
   128  func TestRaku(t *testing.T) {
   129  	if _, err := exec.LookPath("raku"); err != nil {
   130  		t.Skip("could not find 'raku' executable in PATH")
   131  	}
   132  	rakuDir := filepath.Join(projectRoot, "raku", "arith")
   133  	os.Chdir(rakuDir)
   134  	t.Run("SmallStep", test("raku", "arith.raku", "-small-step"))
   135  	t.Run("BigStep", test("raku", "arith.raku", "-big-step"))
   136  }