Skip to content

Commit

Permalink
Notebook tests
Browse files Browse the repository at this point in the history
  • Loading branch information
firelizzard18 committed Apr 4, 2024
1 parent c942a19 commit 305c6a5
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ issues:
linters:
- noprint

- path: ^test/e2e2/generated
linters:
- goheader

- path: ^test/|.*_test\.go
linters:
- noprint
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ retract (
v1.1.0 // Causes consensus failure when run alongside v1.0.x
)

go 1.21
go 1.22.1

replace github.com/julienschmidt/httprouter v1.3.0 => github.com/firelizzard18/httprouter v0.0.0-20231019203155-74063b4f447c

Expand Down Expand Up @@ -68,6 +68,7 @@ require (
github.com/sergi/go-diff v1.2.0
github.com/ulikunitz/xz v0.5.11
github.com/vektra/mockery/v2 v2.23.1
gitlab.com/firelizzard/go-script v0.0.0-20240404234115-d5f0a716003d
go.opentelemetry.io/otel v1.16.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.14.0
go.opentelemetry.io/otel/sdk v1.14.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,8 @@ gitlab.com/ethan.reesor/vscode-notebooks/go-playbooks v0.0.0-20220417214602-1121
gitlab.com/ethan.reesor/vscode-notebooks/go-playbooks v0.0.0-20220417214602-1121b9fae118/go.mod h1:WMjfCTtyNvFXHezq+dfQOiTSaaxfxuy7ycIUkL+Zz24=
gitlab.com/ethan.reesor/vscode-notebooks/yaegi v0.0.0-20220417214422-5c573557938e h1:YYR/xnTbyyJsd+H4pSALxcl0v7HMg1BwuQhmjvCs4Hc=
gitlab.com/ethan.reesor/vscode-notebooks/yaegi v0.0.0-20220417214422-5c573557938e/go.mod h1:Qk5VJRON+aERbKQ3zTZTemeTBoXDfiyQfpbBQ58LWGk=
gitlab.com/firelizzard/go-script v0.0.0-20240404234115-d5f0a716003d h1:RE+FNlXt4u37+Uhuja8JFzJwW3kckNFfIdqVrUPJRs8=
gitlab.com/firelizzard/go-script v0.0.0-20240404234115-d5f0a716003d/go.mod h1:8u+h7N5SG1dgAFbeCC/TN6nvQmoGVaENcb6cwUtQAzg=
go-simpler.org/assert v0.7.0 h1:OzWWZqfNxt8cLS+MlUp6Tgk1HjPkmgdKBq9qvy8lZsA=
go-simpler.org/assert v0.7.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28=
go-simpler.org/musttag v0.9.0 h1:Dzt6/tyP9ONr5g9h9P3cnYWCxeBFRkd0uJL/w+1Mxos=
Expand Down
13 changes: 13 additions & 0 deletions test/e2e2/alice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Alice

Set up Alice with a basic identity: a single-sig key page and a token account.

```go
alice := build.
Identity("alice").Create().
Tokens("tokens").Create("ACME").Add(1e9).Identity().
Book().Page(1).Create().AddCredits(1e9).Book().Identity()
aliceKey := alice.Book().Page(1).
GenerateKey(SignatureTypeED25519)
_, _ = alice, aliceKey
```
13 changes: 13 additions & 0 deletions test/e2e2/bob.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Bob

Set up Bob with a basic identity: a single-sig key page and a token account.

```go
bob := build.
Identity("bob").Create().
Tokens("tokens").Create("ACME").Add(1e9).Identity().
Book().Page(1).Create().AddCredits(1e9).Book().Identity()
bobKey := bob.Book().Page(1).
GenerateKey(SignatureTypeED25519)
_, _ = bob, bobKey
```
27 changes: 27 additions & 0 deletions test/e2e2/example_test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Example notebook test

This is a simple example of a notebook-based test

### Setup

```go
import "./alice.md"
import "./bob.md"

sim := NewSim(t,
simulator.SimpleNetwork(t.Name(), 3, 3),
simulator.Genesis(GenesisTime).With(alice, bob),
)
```

### Send tokens from Alice to Bob

```go
st := sim.BuildAndSubmitTxnSuccessfully(
build.Transaction().For(alice, "tokens").
SendTokens(123, 0).To(bob, "tokens").
SignWith(alice, "book", "1").Version(1).Timestamp(1).PrivateKey(aliceKey))

sim.StepUntil(
Txn(st.TxID).Completes())
```
161 changes: 161 additions & 0 deletions test/e2e2/generate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Copyright 2024 The Accumulate Authors
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

package e2e2

import (
"go/ast"
"go/printer"
"go/token"
"os"
"path/filepath"
"regexp"
"strings"
"testing"

"github.com/russross/blackfriday/v2"
"github.com/stretchr/testify/require"
"gitlab.com/firelizzard/go-script/pkg/script"
)

func TestGenerate(t *testing.T) {
dir, err := os.ReadDir(".")
require.NoError(t, err)

require.NoError(t, os.RemoveAll("generated"))
require.NoError(t, os.MkdirAll("generated", 0755))

for _, ent := range dir {
if ent.IsDir() || !strings.HasSuffix(ent.Name(), "_test.md") {
continue
}

name := strings.TrimSuffix(ent.Name(), "_test.md")
name = reSnake.ReplaceAllStringFunc(name, func(s string) string {
return strings.ToUpper(strings.TrimPrefix(s, "_"))
})

t.Run(name, func(t *testing.T) {
generateTest(t, name, ent.Name())
})
}
}

var reSnake = regexp.MustCompile(`(^|_)\w`)
var reCodeFence = regexp.MustCompile(`^([^\s\{]*)(\{[^\n]*\})?`)

func generateTest(t *testing.T, name, filename string) {
fset := token.NewFileSet()
imports, contents := parseTestMd(t, fset, filename)

body, err := script.ResolveImports(&ast.BlockStmt{
List: contents,
}, func(path string) (ast.Node, error) {
imports, contents := parseTestMd(t, fset, path)
return &ast.File{
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.IMPORT,
Specs: imports,
},
&ast.FuncDecl{
Name: &ast.Ident{Name: "main"},
Body: &ast.BlockStmt{List: contents},
},
},
}, nil
})
require.NoError(t, err)

f := &ast.File{
Name: &ast.Ident{Name: "e2e2"},
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
&ast.ImportSpec{Path: &ast.BasicLit{Value: `"testing"`, Kind: token.STRING}},
&ast.ImportSpec{Path: &ast.BasicLit{Value: `"gitlab.com/accumulatenetwork/accumulate/pkg/build"`, Kind: token.STRING}},
&ast.ImportSpec{Path: &ast.BasicLit{Value: `"gitlab.com/accumulatenetwork/accumulate/protocol"`, Kind: token.STRING}, Name: &ast.Ident{Name: "."}},
&ast.ImportSpec{Path: &ast.BasicLit{Value: `"gitlab.com/accumulatenetwork/accumulate/test/harness"`, Kind: token.STRING}, Name: &ast.Ident{Name: "."}},
&ast.ImportSpec{Path: &ast.BasicLit{Value: `"gitlab.com/accumulatenetwork/accumulate/test/simulator"`, Kind: token.STRING}},
},
},
&ast.GenDecl{
Tok: token.IMPORT,
Specs: imports,
},
&ast.FuncDecl{
Name: &ast.Ident{Name: "Test" + name},
Type: &ast.FuncType{
Params: &ast.FieldList{
List: []*ast.Field{{
Names: []*ast.Ident{{Name: "t"}},
Type: &ast.StarExpr{
X: &ast.SelectorExpr{
X: &ast.Ident{Name: "testing"},
Sel: &ast.Ident{Name: "T"},
},
},
}},
},
},
Body: body,
},
},
}

out, err := os.Create(filepath.Join("generated", strings.TrimSuffix(filename, ".md")+".go"))
require.NoError(t, err)
err = printer.Fprint(out, fset, f)
require.NoError(t, err)
}

func parseTestMd(t *testing.T, fset *token.FileSet, filename string) ([]ast.Spec, []ast.Stmt) {
// Read the file
src, err := os.ReadFile(filename)
require.NoError(t, err)

// Parse the markdown
parser := blackfriday.New(blackfriday.WithExtensions(blackfriday.FencedCode))
doc := parser.Parse(src)

// Extract code blocks
var imports []ast.Spec
var contents []ast.Stmt
doc.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
// Is it a code block?
if node.Type != blackfriday.CodeBlock {
return blackfriday.GoToNext
}

// Is it Go?
m := reCodeFence.FindSubmatch(node.Info)
if len(m) < 2 || string(m[1]) != "go" {
return blackfriday.GoToNext
}

// Parse it
f, err := script.Read(fset, t.Name(), string(node.Literal))
require.NoError(t, err)

for _, i := range f.Imports {
imports = append(imports, i)
}

for _, decl := range f.Decls {
fn, ok := decl.(*ast.FuncDecl)
if !ok || fn.Name.Name != "main" {
contents = append(contents, &ast.DeclStmt{Decl: decl})
} else {
contents = append(contents, fn.Body.List...)
}
}

return blackfriday.GoToNext
})

return imports, contents
}
38 changes: 38 additions & 0 deletions test/e2e2/generated/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package e2e2

import (
"testing"

"gitlab.com/accumulatenetwork/accumulate/pkg/build"
. "gitlab.com/accumulatenetwork/accumulate/protocol"
. "gitlab.com/accumulatenetwork/accumulate/test/harness"
"gitlab.com/accumulatenetwork/accumulate/test/simulator"
)

func TestExample(t *testing.T) {
alice := build.
Identity("alice").Create().
Tokens("tokens").Create("ACME").Add(1e9).Identity().
Book().Page(1).Create().AddCredits(1e9).Book().Identity()
aliceKey := alice.Book().Page(1).
GenerateKey(SignatureTypeED25519)
_, _ = alice, aliceKey
bob := build.
Identity("bob").Create().
Tokens("tokens").Create("ACME").Add(1e9).Identity().
Book().Page(1).Create().AddCredits(1e9).Book().Identity()
bobKey := bob.Book().Page(1).
GenerateKey(SignatureTypeED25519)
_, _ = bob, bobKey
sim := NewSim(t,
simulator.SimpleNetwork(t.Name(), 3, 3),
simulator.Genesis(GenesisTime).With(alice, bob),
)
st := sim.BuildAndSubmitTxnSuccessfully(
build.Transaction().For(alice, "tokens").
SendTokens(123, 0).To(bob, "tokens").
SignWith(alice, "book", "1").Version(1).Timestamp(1).PrivateKey(aliceKey))

sim.StepUntil(
Txn(st.TxID).Completes())
}

0 comments on commit 305c6a5

Please sign in to comment.