Skip to content

Commit

Permalink
better test for encoding values with quotes
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Farrow committed Jun 3, 2021
1 parent 192c127 commit d16f8d2
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 16 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,19 @@ Multiple top-level forms are allowed and returned as an array of Nodes by the de
Writes the Node object in brief format.

```go
var Node Node
var node Node
var out io.Writer
err := Node.Encode(out)
err := node.Encode(out)
```

### Brief XML Output

Writes the Node object in XML format.

```go
var Node Node
var node Node
var out io.Writer
err := Node.WriteXML(out)
err := node.WriteXML(out)
```

XML output uses a template. This serves as an example of using brief with a template.
Expand Down Expand Up @@ -179,15 +179,15 @@ Lookup is a Node method which gets a context value from a value spec.
Slice is a Node method which creates a slice of strings from a sequence of value specs.

```text/template
{{ print .Slice "project.id" "project" }}
{{ .Slice "project.id" "project" }}
```

#### Join

Join is a Node method which combines sequence of strings using a separator from a sequence of value specs.

```text/template
{{ print .Join "/" "project.id" "project" }}
{{ .Join "/" "project.id" "project" }}
```

#### Printf
Expand Down
36 changes: 26 additions & 10 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package brief
import (
"fmt"
"strings"
"unicode"
"text/scanner"
)

// Encode converts a node into brief format
Expand All @@ -20,17 +20,33 @@ func (node *Node) Encode() []byte {
return []byte(out.String())
}

func isIdentRune(ch rune, i int) bool {
return ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0
}

func isSymbol(token string) bool {
for i, ch := range token {
if !isIdentRune(ch, i) {
// NoQuote tests if the value is an identifier or number
func NoQuote(value string) bool {
var s scanner.Scanner
s.Init(strings.NewReader(value))
tok := s.Scan()
var minus bool
for {
switch tok {
case scanner.Ident:
return !minus && s.TokenText() == value
case scanner.Float, scanner.Int:
numval := s.TokenText()
if minus {
numval = "-" + numval
}
return numval == value
case '-':
if minus {
return false
}
minus = true
tok = s.Scan()
default:
return false
}
}
return true

}

func (node *Node) write(out *strings.Builder) []*Node {
Expand All @@ -40,7 +56,7 @@ func (node *Node) write(out *strings.Builder) []*Node {
out.WriteString(":" + node.Name)
}
for key, val := range node.Keys {
if isSymbol(val) {
if NoQuote(val) {
out.WriteString(fmt.Sprintf(" %s:%s", key, val))
continue
}
Expand Down
69 changes: 69 additions & 0 deletions encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,72 @@ func TestEncoder(t *testing.T) {
t.Fatal("before and after not the same")
}
}

func TestNoQuote(t *testing.T) {
tests := []struct {
value string
valid bool
}{
{
value: "one",
valid: true,
},
{
value: "-one",
valid: false,
},
{
value: "-",
valid: false,
},
{
value: "24",
valid: true,
},
{
value: "33.0e4",
valid: true,
},
{
value: "-33.0e4",
valid: true,
},
{
value: "-22",
valid: true,
},
{
value: "- 22",
valid: false,
},
{
value: "24a",
valid: false,
},
{
value: "33.0e-4",
valid: true,
},
{
value: "x-22",
valid: false,
},
{
value: "- - 33",
valid: false,
},
{
value: "go-flags",
valid: false,
},
{
value: "go flags",
valid: false,
},
}
for i, test := range tests {
if brief.NoQuote(test.value) != test.valid {
t.Errorf("%d> failed %s", i, test.value)
}
}
}

0 comments on commit d16f8d2

Please sign in to comment.