Skip to content

Commit

Permalink
Merge branch 'master' of github.com:gnolang/gno into dev/morgan/big-t…
Browse files Browse the repository at this point in the history
…est-refactor
  • Loading branch information
thehowl committed Nov 19, 2024
2 parents 3f9abe1 + 0246761 commit d351434
Show file tree
Hide file tree
Showing 25 changed files with 436 additions and 75 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/BUG-REPORT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
name: Bug Report Template
about: Create a bug report
labels: "🐞 bug"
# NOTE: keep in sync with gnovm/cmd/gno/bug.go
---

Expand Down
3 changes: 3 additions & 0 deletions examples/gno.land/p/moul/mdtable/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module gno.land/p/moul/mdtable

require gno.land/p/demo/urequire v0.0.0-latest
66 changes: 66 additions & 0 deletions examples/gno.land/p/moul/mdtable/mdtable.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Package mdtable provides a simple way to create Markdown tables.
//
// Example usage:
//
// import "gno.land/p/moul/mdtable"
//
// func Render(path string) string {
// table := mdtable.Table{
// Headers: []string{"ID", "Title", "Status", "Date"},
// }
// table.Append([]string{"#1", "Add a new validator", "succeed", "2024-01-01"})
// table.Append([]string{"#2", "Change parameter", "timed out", "2024-01-02"})
// return table.String()
// }
//
// Output:
//
// | ID | Title | Status | Date |
// | --- | --- | --- | --- |
// | #1 | Add a new validator | succeed | 2024-01-01 |
// | #2 | Change parameter | timed out | 2024-01-02 |
package mdtable

import (
"strings"
)

type Table struct {
Headers []string
Rows [][]string
// XXX: optional headers alignment.
}

func (t *Table) Append(row []string) {
t.Rows = append(t.Rows, row)
}

func (t Table) String() string {
// XXX: switch to using text/tabwriter when porting to Gno to support
// better-formatted raw Markdown output.

if len(t.Headers) == 0 && len(t.Rows) == 0 {
return ""
}

var sb strings.Builder

if len(t.Headers) == 0 {
t.Headers = make([]string, len(t.Rows[0]))
}

// Print header.
sb.WriteString("| " + strings.Join(t.Headers, " | ") + " |\n")
sb.WriteString("|" + strings.Repeat(" --- |", len(t.Headers)) + "\n")

// Print rows.
for _, row := range t.Rows {
escapedRow := make([]string, len(row))
for i, cell := range row {
escapedRow[i] = strings.ReplaceAll(cell, "|", "|") // Escape pipe characters.
}
sb.WriteString("| " + strings.Join(escapedRow, " | ") + " |\n")
}

return sb.String()
}
158 changes: 158 additions & 0 deletions examples/gno.land/p/moul/mdtable/mdtable_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package mdtable_test

import (
"testing"

"gno.land/p/demo/urequire"
"gno.land/p/moul/mdtable"
)

// XXX: switch to `func Example() {}` when supported.
func TestExample(t *testing.T) {
table := mdtable.Table{
Headers: []string{"ID", "Title", "Status"},
Rows: [][]string{
{"#1", "Add a new validator", "succeed"},
{"#2", "Change parameter", "timed out"},
{"#3", "Fill pool", "active"},
},
}

got := table.String()
expected := `| ID | Title | Status |
| --- | --- | --- |
| #1 | Add a new validator | succeed |
| #2 | Change parameter | timed out |
| #3 | Fill pool | active |
`

urequire.Equal(t, got, expected)
}

func TestTableString(t *testing.T) {
tests := []struct {
name string
table mdtable.Table
expected string
}{
{
name: "With Headers and Rows",
table: mdtable.Table{
Headers: []string{"ID", "Title", "Status", "Date"},
Rows: [][]string{
{"#1", "Add a new validator", "succeed", "2024-01-01"},
{"#2", "Change parameter", "timed out", "2024-01-02"},
},
},
expected: `| ID | Title | Status | Date |
| --- | --- | --- | --- |
| #1 | Add a new validator | succeed | 2024-01-01 |
| #2 | Change parameter | timed out | 2024-01-02 |
`,
},
{
name: "Without Headers",
table: mdtable.Table{
Rows: [][]string{
{"#1", "Add a new validator", "succeed", "2024-01-01"},
{"#2", "Change parameter", "timed out", "2024-01-02"},
},
},
expected: `| | | | |
| --- | --- | --- | --- |
| #1 | Add a new validator | succeed | 2024-01-01 |
| #2 | Change parameter | timed out | 2024-01-02 |
`,
},
{
name: "Without Rows",
table: mdtable.Table{
Headers: []string{"ID", "Title", "Status", "Date"},
},
expected: `| ID | Title | Status | Date |
| --- | --- | --- | --- |
`,
},
{
name: "With Pipe Character in Content",
table: mdtable.Table{
Headers: []string{"ID", "Title", "Status", "Date"},
Rows: [][]string{
{"#1", "Add a new | validator", "succeed", "2024-01-01"},
{"#2", "Change parameter", "timed out", "2024-01-02"},
},
},
expected: `| ID | Title | Status | Date |
| --- | --- | --- | --- |
| #1 | Add a new | validator | succeed | 2024-01-01 |
| #2 | Change parameter | timed out | 2024-01-02 |
`,
},
{
name: "With Varying Row Sizes", // XXX: should we have a different behavior?
table: mdtable.Table{
Headers: []string{"ID", "Title"},
Rows: [][]string{
{"#1", "Add a new validator"},
{"#2", "Change parameter", "Extra Column"},
{"#3", "Fill pool"},
},
},
expected: `| ID | Title |
| --- | --- |
| #1 | Add a new validator |
| #2 | Change parameter | Extra Column |
| #3 | Fill pool |
`,
},
{
name: "With UTF-8 Characters",
table: mdtable.Table{
Headers: []string{"ID", "Title", "Status", "Date"},
Rows: [][]string{
{"#1", "Café", "succeed", "2024-01-01"},
{"#2", "München", "timed out", "2024-01-02"},
{"#3", "São Paulo", "active", "2024-01-03"},
},
},
expected: `| ID | Title | Status | Date |
| --- | --- | --- | --- |
| #1 | Café | succeed | 2024-01-01 |
| #2 | München | timed out | 2024-01-02 |
| #3 | São Paulo | active | 2024-01-03 |
`,
},
{
name: "With no Headers and no Rows",
table: mdtable.Table{},
expected: ``,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.table.String()
urequire.Equal(t, got, tt.expected)
})
}
}

func TestTableAppend(t *testing.T) {
table := mdtable.Table{
Headers: []string{"ID", "Title", "Status", "Date"},
}

// Use the Append method to add rows to the table
table.Append([]string{"#1", "Add a new validator", "succeed", "2024-01-01"})
table.Append([]string{"#2", "Change parameter", "timed out", "2024-01-02"})
table.Append([]string{"#3", "Fill pool", "active", "2024-01-03"})
got := table.String()

expected := `| ID | Title | Status | Date |
| --- | --- | --- | --- |
| #1 | Add a new validator | succeed | 2024-01-01 |
| #2 | Change parameter | timed out | 2024-01-02 |
| #3 | Fill pool | active | 2024-01-03 |
`
urequire.Equal(t, got, expected)
}
12 changes: 12 additions & 0 deletions examples/gno.land/r/demo/emit/emit.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Package emit demonstrates how to use the std.Emit() function
// to emit Gno events that can be used to track data changes off-chain.
// std.Emit is variadic; apart from the event name, it can take in any number of key-value pairs to emit.
package emit

import (
"std"
)

func Emit(value string) {
std.Emit("EventName", "key", value)
}
1 change: 1 addition & 0 deletions examples/gno.land/r/demo/emit/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/r/demo/emit
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
package main

import "gno.land/r/demo/event"
import "gno.land/r/demo/emit"

func main() {
event.Emit("foo")
event.Emit("bar")
emit.Emit("foo")
emit.Emit("bar")
}

// Events:
// [
// {
// "type": "TAG",
// "type": "EventName",
// "attrs": [
// {
// "key": "key",
// "value": "foo"
// }
// ],
// "pkg_path": "gno.land/r/demo/event",
// "pkg_path": "gno.land/r/demo/emit",
// "func": "Emit"
// },
// {
// "type": "TAG",
// "type": "EventName",
// "attrs": [
// {
// "key": "key",
// "value": "bar"
// }
// ],
// "pkg_path": "gno.land/r/demo/event",
// "pkg_path": "gno.land/r/demo/emit",
// "func": "Emit"
// }
// ]
9 changes: 0 additions & 9 deletions examples/gno.land/r/demo/event/event.gno

This file was deleted.

1 change: 0 additions & 1 deletion examples/gno.land/r/demo/event/gno.mod

This file was deleted.

1 change: 1 addition & 0 deletions examples/gno.land/r/demo/hello_world/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/r/demo/hello_world
17 changes: 17 additions & 0 deletions examples/gno.land/r/demo/hello_world/hello.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Package hello_world demonstrates the usage of the Render() function.
// Render() can be called via the vm/qrender ABCI query off-chain to
// retrieve realm state or any other custom data defined by the realm
// developer. The vm/qrender query allows for additional data to be
// passed in with the call, which can be utilized as the path argument
// to the Render() function. This allows developers to create different
// "renders" of their realms depending on the data which is passed in,
// such as pagination, admin dashboards, and more.
package hello_world

func Render(path string) string {
if path == "" {
return "# Hello, 世界!"
}

return "# Hello, " + path + "!"
}
19 changes: 19 additions & 0 deletions examples/gno.land/r/demo/hello_world/hello_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package hello_world

import (
"testing"
)

func TestHello(t *testing.T) {
expected := "# Hello, 世界!"
got := Render("")
if got != expected {
t.Fatalf("Expected %s, got %s", expected, got)
}

got = Render("world")
expected = "# Hello, world!"
if got != expected {
t.Fatalf("Expected %s, got %s", expected, got)
}
}
21 changes: 11 additions & 10 deletions gnovm/pkg/gnolang/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,17 @@ func (loc Location) IsZero() bool {
type GnoAttribute string

const (
ATTR_PREPROCESSED GnoAttribute = "ATTR_PREPROCESSED"
ATTR_PREDEFINED GnoAttribute = "ATTR_PREDEFINED"
ATTR_TYPE_VALUE GnoAttribute = "ATTR_TYPE_VALUE"
ATTR_TYPEOF_VALUE GnoAttribute = "ATTR_TYPEOF_VALUE"
ATTR_IOTA GnoAttribute = "ATTR_IOTA"
ATTR_LOCATIONED GnoAttribute = "ATTR_LOCATIONE" // XXX DELETE
ATTR_GOTOLOOP_STMT GnoAttribute = "ATTR_GOTOLOOP_STMT" // XXX delete?
ATTR_LOOP_DEFINES GnoAttribute = "ATTR_LOOP_DEFINES" // []Name defined within loops.
ATTR_LOOP_USES GnoAttribute = "ATTR_LOOP_USES" // []Name loop defines actually used.
ATTR_SHIFT_RHS GnoAttribute = "ATTR_SHIFT_RHS"
ATTR_PREPROCESSED GnoAttribute = "ATTR_PREPROCESSED"
ATTR_PREDEFINED GnoAttribute = "ATTR_PREDEFINED"
ATTR_TYPE_VALUE GnoAttribute = "ATTR_TYPE_VALUE"
ATTR_TYPEOF_VALUE GnoAttribute = "ATTR_TYPEOF_VALUE"
ATTR_IOTA GnoAttribute = "ATTR_IOTA"
ATTR_LOCATIONED GnoAttribute = "ATTR_LOCATIONE" // XXX DELETE
ATTR_GOTOLOOP_STMT GnoAttribute = "ATTR_GOTOLOOP_STMT" // XXX delete?
ATTR_LOOP_DEFINES GnoAttribute = "ATTR_LOOP_DEFINES" // []Name defined within loops.
ATTR_LOOP_USES GnoAttribute = "ATTR_LOOP_USES" // []Name loop defines actually used.
ATTR_SHIFT_RHS GnoAttribute = "ATTR_SHIFT_RHS"
ATTR_LAST_BLOCK_STMT GnoAttribute = "ATTR_LAST_BLOCK_STMT"
)

type Attributes struct {
Expand Down
Loading

0 comments on commit d351434

Please sign in to comment.