1
0
Fork 0

Green tests

This commit is contained in:
Gregory Eremin 2015-02-18 22:33:57 +07:00
parent d5663a7876
commit 3faf1adbad
4 changed files with 90 additions and 75 deletions

View File

@ -22,7 +22,7 @@ func NewBytesBuffer(input []byte) *BytesBuffer {
func (b *BytesBuffer) Next() rune { func (b *BytesBuffer) Next() rune {
var buf bytes.Buffer var buf bytes.Buffer
for b.pos < b.size-1 { for b.pos < b.size {
buf.WriteByte(b.input[b.pos]) buf.WriteByte(b.input[b.pos])
b.pos++ b.pos++
if ok := utf8.FullRune(buf.Bytes()); ok { if ok := utf8.FullRune(buf.Bytes()); ok {

View File

@ -232,20 +232,25 @@ func lexBool(l *Lexer) stateFn {
} }
func lexNumber(l *Lexer) stateFn { func lexNumber(l *Lexer) stateFn {
numDots := 0 var (
numDots = 0
prev rune
cur rune
)
for { for {
switch r := l.next(); r { switch cur = l.next(); cur {
case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0': case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0':
case '.': case '.':
numDots++ numDots++
default: default:
l.backup(1) l.backup(1)
if numDots > 1 || r == '.' { if numDots > 1 || prev == '.' {
return l.errorf("Invalid number: %q", l.val()) return l.errorf("Invalid number: %q", l.val())
} }
l.emit(Number) l.emit(Number)
return lexInitial return lexInitial
} }
prev = cur
} }
} }

View File

@ -1,80 +1,85 @@
package lexer package lexer
import "testing" import (
"runtime"
"testing"
"github.com/localhots/punk/buffer"
)
func TestEmpty(t *testing.T) { func TestEmpty(t *testing.T) {
compare(t, lex(""), []Item{ compare(t, lex(""), []Item{
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
} }
func TestNull(t *testing.T) { func TestNull(t *testing.T) {
compare(t, lex("null"), []Item{ compare(t, lex("null"), []Item{
Item{Null, "null", 0}, Item{Null, "null", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
} }
func TesBool(t *testing.T) { func TesBool(t *testing.T) {
compare(t, lex("true"), []Item{ compare(t, lex("true"), []Item{
Item{Bool, "true", 0}, Item{Bool, "true", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
compare(t, lex("false"), []Item{ compare(t, lex("false"), []Item{
Item{Bool, "false", 0}, Item{Bool, "false", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
} }
func TestString(t *testing.T) { func TestString(t *testing.T) {
compare(t, lex(`"foo"`), []Item{ compare(t, lex(`"foo"`), []Item{
Item{String, "foo", 0}, Item{String, "foo", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
} }
func TestNumber(t *testing.T) { func TestNumber(t *testing.T) {
compare(t, lex("123"), []Item{ compare(t, lex("123"), []Item{
Item{Number, "123", 0}, Item{Number, "123", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
compare(t, lex("123.456"), []Item{ compare(t, lex("123.456"), []Item{
Item{Number, "123.456", 0}, Item{Number, "123.456", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
compare(t, lex("123.456.789"), []Item{ compare(t, lex("123.456.789"), []Item{
Item{Error, `Invalid number: "123.456.789"`, 0}, Item{Error, `Invalid number: "123.456.789"`, 0, 0},
}) })
compare(t, lex("123."), []Item{ compare(t, lex("123."), []Item{
Item{Error, `Invalid number: "123."`, 0}, Item{Error, `Invalid number: "123."`, 0, 0},
}) })
} }
func TestArray(t *testing.T) { func TestArray(t *testing.T) {
compare(t, lex(`[1, "2", 3]`), []Item{ compare(t, lex(`[1, "2", 3]`), []Item{
Item{BracketOpen, "[", 0}, Item{BracketOpen, "[", 0, 0},
Item{Number, "1", 0}, Item{Number, "1", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{String, "2", 0}, Item{String, "2", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{Number, "3", 0}, Item{Number, "3", 0, 0},
Item{BracketClose, "]", 0}, Item{BracketClose, "]", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
} }
func TestObject(t *testing.T) { func TestObject(t *testing.T) {
compare(t, lex(`{"a": 1, "b": 2}`), []Item{ compare(t, lex(`{"a": 1, "b": 2}`), []Item{
Item{BraceOpen, "{", 0}, Item{BraceOpen, "{", 0, 0},
Item{String, "a", 0}, Item{String, "a", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{Number, "1", 0}, Item{Number, "1", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{String, "b", 0}, Item{String, "b", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{Number, "2", 0}, Item{Number, "2", 0, 0},
Item{BraceClose, "}", 0}, Item{BraceClose, "}", 0, 0},
Item{EOF, "", 0}, Item{EOF, "\x00", 0, 0},
}) })
} }
@ -92,65 +97,69 @@ func TestEverything(t *testing.T) {
} }
` `
compare(t, lex(input), []Item{ compare(t, lex(input), []Item{
Item{BraceOpen, "{", 0}, Item{BraceOpen, "{", 0, 0},
Item{String, "foo", 0}, Item{String, "foo", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{Bool, "true", 0}, Item{Bool, "true", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{String, "bar", 0}, Item{String, "bar", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{Bool, "false", 0}, Item{Bool, "false", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{String, "zilch", 0}, Item{String, "zilch", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{Null, "null", 0}, Item{Null, "null", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{String, "numbers", 0}, Item{String, "numbers", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{BracketOpen, "[", 0}, Item{BracketOpen, "[", 0, 0},
Item{Number, "1", 0}, Item{Number, "1", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{Number, "23", 0}, Item{Number, "23", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{Number, "4.56", 0}, Item{Number, "4.56", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{Number, "7.89", 0}, Item{Number, "7.89", 0, 0},
Item{BracketClose, "]", 0}, Item{BracketClose, "]", 0, 0},
Item{Comma, ",", 0}, Item{Comma, ",", 0, 0},
Item{String, "bullshit", 0}, Item{String, "bullshit", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{BraceOpen, "{", 0}, Item{BraceOpen, "{", 0, 0},
Item{String, "nothing", 0}, Item{String, "nothing", 0, 0},
Item{Colon, ":", 0}, Item{Colon, ":", 0, 0},
Item{String, "anything", 0}, Item{String, "anything", 0, 0},
Item{BraceClose, "}", 0}, Item{BraceClose, "}", 0, 0},
Item{Error, "Unexpected symbol: !", 0}, Item{Error, "Unexpected symbol: '!'", 0, 0},
}) })
} }
func compare(t *testing.T, reality, expectations []Item) { func compare(t *testing.T, reality, expectations []Item) {
if len(reality) != len(expectations) { if len(reality) != len(expectations) {
t.Errorf("Expected %d tokens, got %d", len(reality), len(expectations)) t.Errorf("Expected %d tokens, got %d", len(reality), len(expectations))
t.Error(runtime.Caller(1))
return return
} }
for i, exp := range expectations { for i, exp := range expectations {
if exp.Token != reality[i].Token { if exp.Token != reality[i].Token {
t.Errorf("Expected an %s token, got %s", exp, reality[i]) t.Errorf("Expected an %s token, got %s", exp, reality[i])
t.Error(runtime.Caller(1))
continue continue
} }
if exp.Val != reality[i].Val { if exp.Val != reality[i].Val {
t.Errorf("Expected an %s token to hold value of %q, got %q", exp, exp.Val, reality[i].Val) t.Errorf("Expected an %s token to hold value of %q, got %q", exp, exp.Val, reality[i].Val)
t.Error(runtime.Caller(1))
} }
} }
} }
func lex(json string) []Item { func lex(json string) []Item {
l := New(json) buf := buffer.NewBytesBuffer([]byte(json))
go l.Run() lex := New(buf)
go lex.Run()
items := []Item{} items := []Item{}
for { for {
if item, ok := l.NextItem(); ok { if item, ok := lex.NextItem(); ok {
items = append(items, item) items = append(items, item)
} else { } else {
break break

View File

@ -35,7 +35,7 @@ func New(buf buffer.Bufferer, sels []string) *Parser {
} }
} }
// Starts parsing // Parse all and return matches
func (p *Parser) Parse() map[string][]interface{} { func (p *Parser) Parse() map[string][]interface{} {
p.ParseStream() p.ParseStream()
out := map[string][]interface{}{} out := map[string][]interface{}{}
@ -49,6 +49,7 @@ func (p *Parser) Parse() map[string][]interface{} {
return out return out
} }
// Starts parsing
func (p *Parser) ParseStream() <-chan Match { func (p *Parser) ParseStream() <-chan Match {
go p.lex.Run() go p.lex.Run()
go func() { go func() {