-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7f76c51
commit 8f81d14
Showing
8 changed files
with
299 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ | |
!/.env.sample | ||
!/.cruft.json | ||
!/.goreleaser.yaml | ||
|
||
!/test/* | ||
!.github/workflows/*.yml | ||
|
||
!*.go | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,16 @@ | ||
module github.com/dyne/fouter | ||
|
||
module github.com/ForkbombEu/fouter | ||
go 1.22 | ||
|
||
require ( | ||
github.com/FilippoTrotter/slangroom-go v0.0.0-20241003095650-aada02d0ab90 | ||
github.com/gorilla/mux v1.8.1 | ||
github.com/stretchr/testify v1.9.0 | ||
) | ||
|
||
require ( | ||
github.com/amenzhinsky/go-memexec v0.7.1 // indirect | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
github.com/FilippoTrotter/slangroom-go v0.0.0-20241003095650-aada02d0ab90 h1:nuq9jkWM+wY4UfvXHpE0mN/C/W3eIzQp2bds0L9Zao4= | ||
github.com/FilippoTrotter/slangroom-go v0.0.0-20241003095650-aada02d0ab90/go.mod h1:+hMvWLDLPvTCwpx1BFBIoSX/cIlIZDWPvzQ+U1pP3X0= | ||
github.com/amenzhinsky/go-memexec v0.7.1 h1:DVm4cXzklaNWZoTJgZUi/dlXtelhC7QBtX4luKjl1qk= | ||
github.com/amenzhinsky/go-memexec v0.7.1/go.mod h1:ApTO9/i2bcii7kvIXi74gum+/zYDzkiOXtuBZoYOKVE= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= | ||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= | ||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= | ||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg= | ||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
||
slang "github.com/FilippoTrotter/slangroom-go" // Change this to dyne/slangroom-exec once merged | ||
"github.com/gorilla/mux" | ||
) | ||
|
||
const baseDir = "." | ||
|
||
// Function to find all .slang files recursively in the directory and return a map of directories to their files | ||
func findSlangFiles(dir string) (map[string][]string, error) { | ||
slangFiles := make(map[string][]string) | ||
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { | ||
if err != nil { | ||
return err | ||
} | ||
if !info.IsDir() && strings.HasSuffix(info.Name(), ".slang") { | ||
relativePath, _ := filepath.Rel(baseDir, path) // Get the relative path | ||
dir := filepath.Dir(relativePath) | ||
slangFiles[dir] = append(slangFiles[dir], relativePath) | ||
} | ||
return nil | ||
}) | ||
return slangFiles, err | ||
} | ||
|
||
// Handler to print the content of the .slang file and provide a button to execute it | ||
func slangFilePageHandler(filePath string) http.HandlerFunc { | ||
return func(w http.ResponseWriter, r *http.Request) { | ||
content, err := os.ReadFile(filePath) | ||
if err != nil { | ||
http.Error(w, "Error reading file", http.StatusInternalServerError) | ||
return | ||
} | ||
w.Header().Set("Content-Type", "text/html") | ||
fmt.Fprintf(w, "<html><body><h1>%s</h1><pre>%s</pre>", filepath.Base(filePath), string(content)) | ||
|
||
relativePath, _ := filepath.Rel(baseDir, filePath) | ||
fmt.Fprintf(w, `<form method="POST" action="/slang/execute/%s"> | ||
<button type="submit">Execute %s</button> | ||
</form>`, relativePath, filepath.Base(filePath)) | ||
|
||
fmt.Fprintln(w, "</body></html>") | ||
} | ||
} | ||
|
||
// Handler to execute the .slang file content on a POST request | ||
func executeSlangFileHandler(filePath string) http.HandlerFunc { | ||
return func(w http.ResponseWriter, r *http.Request) { | ||
if r.Method != http.MethodPost { | ||
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) | ||
return | ||
} | ||
|
||
content, err := os.ReadFile(filePath) | ||
if err != nil { | ||
http.Error(w, "Error reading file", http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
result, success := slang.SlangroomExec("", string(content), "", "", "", "") | ||
if !success { | ||
http.Error(w, "Error executing slang file: "+result.Logs, http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
output := map[string]interface{}{ | ||
"output": result.Output, | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
if err := json.NewEncoder(w).Encode(output); err != nil { | ||
http.Error(w, "Error encoding output to JSON", http.StatusInternalServerError) | ||
} | ||
} | ||
} | ||
|
||
// Handler to list all available .slang files, grouped by directory | ||
func listSlangFilesHandler(slangFiles map[string][]string) http.HandlerFunc { | ||
return func(w http.ResponseWriter, r *http.Request) { | ||
w.Header().Set("Content-Type", "text/html") | ||
fmt.Fprintln(w, "<html><body><h1>Available contract files:</h1>") | ||
|
||
for dir, files := range slangFiles { | ||
fmt.Fprintf(w, "<h2>Directory: %s</h2><ul>", dir) | ||
|
||
for _, file := range files { | ||
fileName := filepath.Base(file) | ||
// Create the correct link that includes the directory | ||
// Here, we assume the path is already relative to the baseDir | ||
// and it should include the directory in the href | ||
link := fmt.Sprintf("/slang/%s/%s", dir, fileName) // Construct the correct href | ||
|
||
// Display the link with the correct href and text | ||
fmt.Fprintf(w, `<li><a href="%s">%s/%s</a></li>`, link, dir, fileName) | ||
} | ||
|
||
fmt.Fprintln(w, "</ul>") | ||
} | ||
|
||
fmt.Fprintln(w, "</body></html>") | ||
} | ||
} | ||
|
||
func main() { | ||
r := mux.NewRouter() | ||
|
||
slangFiles, err := findSlangFiles(baseDir) | ||
if err != nil { | ||
log.Fatalf("Error finding .slang files: %v", err) | ||
} | ||
|
||
r.HandleFunc("/slang/", listSlangFilesHandler(slangFiles)).Methods("GET") | ||
|
||
// For each file, create an API endpoint to show its content and add an execution button | ||
for _, files := range slangFiles { | ||
for _, file := range files { | ||
// Create a handler to show file content and an execute button | ||
r.HandleFunc(fmt.Sprintf("/slang/%s", file), slangFilePageHandler(file)).Methods("GET") | ||
|
||
// Create a handler to execute the file | ||
r.HandleFunc(fmt.Sprintf("/slang/execute/%s", file), executeSlangFileHandler(file)).Methods("POST") | ||
} | ||
} | ||
|
||
fmt.Println("Starting server on :3000") | ||
fmt.Println("Access the contract files at: http://localhost:3000/slang/") | ||
log.Fatal(http.ListenAndServe(":3000", r)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"net/http" | ||
"net/http/httptest" | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestListSlangFiles(t *testing.T) { | ||
// Sample slang files data for testing | ||
slangFiles := map[string][]string{ | ||
"testdir": {"file1.slang", "file2.slang"}, | ||
"testdir2": {"file3.slang"}, | ||
} | ||
|
||
// Create a request to pass to the handler | ||
req, err := http.NewRequest("GET", "/slang/", nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
// Create a ResponseRecorder to record the response | ||
rr := httptest.NewRecorder() | ||
|
||
// Create the handler | ||
handler := listSlangFilesHandler(slangFiles) | ||
|
||
// Call the handler | ||
handler.ServeHTTP(rr, req) | ||
|
||
// Check the response status code | ||
assert.Equal(t, http.StatusOK, rr.Code) | ||
|
||
// Check that the response contains the expected content | ||
assert.Contains(t, rr.Body.String(), "<h1>Available contract files:</h1>") | ||
assert.Contains(t, rr.Body.String(), "<h2>Directory: testdir</h2>") | ||
assert.Contains(t, rr.Body.String(), "<h2>Directory: testdir2</h2>") | ||
assert.Contains(t, rr.Body.String(), "<a href=\"/slang/testdir/file1.slang\">testdir/file1.slang</a>") | ||
assert.Contains(t, rr.Body.String(), "<a href=\"/slang/testdir/file2.slang\">testdir/file2.slang</a>") | ||
assert.Contains(t, rr.Body.String(), "<a href=\"/slang/testdir2/file3.slang\">testdir2/file3.slang</a>") | ||
} | ||
|
||
func TestSlangFilePage(t *testing.T) { | ||
// Set up a test slang file | ||
testFileName := "testfile.slang" | ||
testFileContent := "Given nothing\nThen print the string 'Test Successful'" | ||
_ = os.WriteFile(testFileName, []byte(testFileContent), 0644) | ||
defer os.Remove(testFileName) // Cleanup after test | ||
|
||
req, err := http.NewRequest("GET", "/slang/"+testFileName, nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
rr := httptest.NewRecorder() | ||
handler := slangFilePageHandler(testFileName) | ||
|
||
handler.ServeHTTP(rr, req) | ||
|
||
// Check the response code | ||
assert.Equal(t, http.StatusOK, rr.Code) | ||
|
||
// Check if the file content is in the response | ||
assert.Contains(t, rr.Body.String(), testFileContent) | ||
|
||
// Check for the execution button in the response | ||
assert.Contains(t, rr.Body.String(), `<button type="submit">Execute testfile.slang</button>`) | ||
} | ||
|
||
func TestExecuteSlangFile(t *testing.T) { | ||
// Set up a test slang file | ||
testFileName := "testexecfile.slang" | ||
testFileContent := `Given nothing | ||
Then print the string 'Execution Successful'` | ||
_ = os.WriteFile(testFileName, []byte(testFileContent), 0644) | ||
defer os.Remove(testFileName) // Cleanup after test | ||
|
||
// Simulate a POST request to execute the slang file | ||
req, err := http.NewRequest("POST", "/slang/execute/"+testFileName, nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
rr := httptest.NewRecorder() | ||
handler := executeSlangFileHandler(testFileName) | ||
|
||
handler.ServeHTTP(rr, req) | ||
|
||
// Check the response code | ||
assert.Equal(t, http.StatusOK, rr.Code) | ||
|
||
// Check the output of the execution (adapt based on your expected output) | ||
var result map[string]interface{} | ||
err = json.Unmarshal(rr.Body.Bytes(), &result) | ||
assert.NoError(t, err, "Failed to unmarshal output") | ||
assert.Contains(t, result["output"], "Execution_Successful") | ||
} | ||
|
||
func TestInvalidRequestMethod(t *testing.T) { | ||
req, err := http.NewRequest("GET", "/slang/execute/testfile.slang", nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
rr := httptest.NewRecorder() | ||
handler := executeSlangFileHandler("testfile.slang") // Assuming a dummy file for handler | ||
|
||
handler.ServeHTTP(rr, req) | ||
|
||
// Check the response code for invalid method | ||
assert.Equal(t, http.StatusMethodNotAllowed, rr.Code) | ||
assert.Contains(t, rr.Body.String(), "Invalid request method") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Given nothing | ||
Then print the string 'Hello World!' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Rule unknown ignore | ||
Given I fetch the local timestamp in seconds and output into 'timestamp' | ||
Given I have a 'time' named 'timestamp' | ||
Then print the string 'Welcome to the Slangroom World' | ||
Then print the 'timestamp' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Rule unknown ignore | ||
Given I fetch the local timestamp in seconds and output into 'timestamp' | ||
Given I have a 'number' named 'timestamp' | ||
Then print the 'timestamp' |