diff --git a/modules/compiler_v2/go_compiler_v2/go_compiler.go b/modules/compiler_v2/go_compiler_v2/go_compiler.go index 800797b92fd3d5cd83723cfe5db05a120d91d590..ead228f6281c5930a82ed521aa656baf5e086850 100644 --- a/modules/compiler_v2/go_compiler_v2/go_compiler.go +++ b/modules/compiler_v2/go_compiler_v2/go_compiler.go @@ -4,9 +4,11 @@ import ( "compiler_V2/consts" "compiler_V2/utils" "os" + "regexp" ) const fileName = "main.go" +const testFileName = "main_test.go" type GoCompiler struct{} @@ -27,19 +29,41 @@ func (gb *GoCompiler) CheckCompileErrors(srcCode []byte) ([]byte, error) { utils.SetupTempFolders(consts.TempOutputDir) defer utils.RemoveTempFolders(consts.TempOutputDir) - // Write code to file - err := os.WriteFile(consts.TempOutputDir+fileName, srcCode, 0644) + // Create regex to extract test functions from srcCode + re := regexp.MustCompile(`(?m)^func\s+(Test\w+)\s*\(t\s+\*testing\.T\)\s*{[\s\S]*?^}`) + + // Get all test functions from srcCode + testFunctions := re.FindAllString(string(srcCode), -1) + + // Remove the test code from the main code + nonTestContent := re.ReplaceAllString(string(srcCode), "") + + // Write code to main file + err := os.WriteFile(consts.TempOutputDir+fileName, []byte(nonTestContent), 0644) if err != nil { return nil, err } - // Init go mod and tidy - cmdString := "go mod init tempOutput && go mod tidy " + + // Construct the content for the _test.go file. + testFileContent := "package main\n\n" + for _, match := range testFunctions { + testFileContent += match + "\n\n" + } + + // Write code to test file, we need this since the tests are in the same file as the code + err2 := os.WriteFile(consts.TempOutputDir+testFileName, []byte(testFileContent), 0644) + if err2 != nil { + return nil, err2 + } + + // Init go mod, tidy (for dependencies) and goimports (for imports) + cmdString := "go mod init tempOutput && go mod tidy && goimports -w ." // Run go build cmdString += " && go build -o main " + fileName // Run tests - cmdString += " && go test " + fileName + cmdString += " && go test -v " cmd := utils.MakeCommand(cmdString) cmd.Dir = consts.TempOutputDir diff --git a/modules/compiler_v2/go_compiler_v2/go_compiler_test.go b/modules/compiler_v2/go_compiler_v2/go_compiler_test.go index 02ea84c6c7360a29aa4bb14687849b29060767df..f8b1fb9fd7d171fd05a3cd5c77ce71fdbc43ed98 100644 --- a/modules/compiler_v2/go_compiler_v2/go_compiler_test.go +++ b/modules/compiler_v2/go_compiler_v2/go_compiler_test.go @@ -31,9 +31,9 @@ func TestCompileStringToGo(t *testing.T) { filename: "should_compile_and_run_tests", shouldCompile: true, }, - { - filename: "should_compile_with_faulty_test", - shouldCompile: true, + { // TODO might change name from should compile to should succeed + filename: "should_compile_with_faulty_test", // Code is syntactically correct, but the test is faulty + shouldCompile: false, // Here the test is faulty, so it will get a compiler error }, } diff --git a/modules/compiler_v2/go_compiler_v2/should_compile_and_run_tests b/modules/compiler_v2/go_compiler_v2/should_compile_and_run_tests index 32c15eef9526acc3ee3129281f7650ba6732b35d..2ceae9fdebbbba961455fdc3ef167c1d0356966a 100644 --- a/modules/compiler_v2/go_compiler_v2/should_compile_and_run_tests +++ b/modules/compiler_v2/go_compiler_v2/should_compile_and_run_tests @@ -1,48 +1,72 @@ package main import ( - "errors" - "fmt" - "testing" + "errors" + "fmt" + "testing" ) // Divide divides two numbers and returns the result. // Returns an error if division by zero is attempted. func Divide(a, b float64) (float64, error) { - if b == 0 { - return 0, errors.New("cannot divide by zero") - } - return a / b, nil + if b == 0 { + return 0, errors.New("cannot divide by zero") + } + return a / b, nil } // Test cases for Divide function func TestDivide(t *testing.T) { - // Test case 1: Normal division - result, err := Divide(10, 2) - if err != nil || result != 5 { - t.Errorf("Expected 5, got %v, error: %v", result, err) - } + tests := []struct { + name string + a float64 + b float64 + expected float64 + wantErr bool + }{ + { + name: "Normal division", + a: 10, + b: 2, + expected: 5, + wantErr: false, + }, + { + name: "Division by zero", + a: 10, + b: 0, + expected: 0, // expected is not used when wantErr is true + wantErr: true, + }, + { + name: "Division with negative numbers", + a: -10, + b: 2, + expected: -5, + wantErr: false, + }, + } - // Test case 2: Division by zero - _, err = Divide(10, 0) - if err == nil { - t.Error("Expected error for division by zero, got nil") - } - - // Test case 3: Division with negative numbers - result, err = Divide(-10, 2) - if err != nil || result != -5 { - t.Errorf("Expected -5, got %v, error: %v", result, err) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := Divide(tt.a, tt.b) + if (err != nil) != tt.wantErr { + t.Errorf("Expected error: %v, got: %v", tt.wantErr, err) + } + if !tt.wantErr && result != tt.expected { + t.Errorf("Expected result: %v, got: %v", tt.expected, result) + } + }) + } } // main function for demonstration purposes func main() { - a, b := 10.0, 2.0 - result, err := Divide(a, b) - if err != nil { - fmt.Println("Error:", err) - } else { - fmt.Printf("Result of %.2f / %.2f = %.2f\n", a, b, result) - } + a, b := 10.0, 2.0 + result, err := Divide(a, b) + if err != nil { + fmt.Println("Error:", err) + } else { + fmt.Printf("Result of %.2f / %.2f = %.2f\n", a, b, result) + } }