pqarrays

Paddy 2015-04-19 Child:9a415db0346a

0:bfe2a4af6bdf Go to Latest

pqarrays/lexer_test.go

First pass implementation. Use a lexer to generate tokens out of the Array type responses that PostgreSQL will send. Write a parser for string[] array types. Create a StringArray type that fulfills the driver.Valuer and sql.Scanner interfaces using the parser and lexer.

History
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/lexer_test.go	Sun Apr 19 23:47:36 2015 -0400
     1.3 @@ -0,0 +1,44 @@
     1.4 +package pqarrays
     1.5 +
     1.6 +import (
     1.7 +	"testing"
     1.8 +)
     1.9 +
    1.10 +var testInputs = map[string][]token{
    1.11 +	``:                                       []token{{typ: tokenError, val: "expected array to start before "}},
    1.12 +	`{}`:                                     []token{{typ: tokenArrayStart, val: "{"}, {typ: tokenArrayEnd, val: "}"}},
    1.13 +	`{lions}`:                                []token{{typ: tokenArrayStart, val: "{"}, {typ: tokenString, val: "lions"}, {typ: tokenArrayEnd, val: "}"}},
    1.14 +	`{lions,tigers}`:                         []token{{typ: tokenArrayStart, val: "{"}, {typ: tokenString, val: "lions"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "tigers"}, {typ: tokenArrayEnd, val: "}"}},
    1.15 +	`{lions,tigers,bears}`:                   []token{{typ: tokenArrayStart, val: "{"}, {typ: tokenString, val: "lions"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "tigers"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "bears"}, {typ: tokenArrayEnd, val: "}"}},
    1.16 +	`{lions,tigers,bears,"oh my!"}`:          []token{{typ: tokenArrayStart, val: "{"}, {typ: tokenString, val: "lions"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "tigers"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "bears"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "oh my!"}, {typ: tokenArrayEnd, val: "}"}},
    1.17 +	`{{two,dimensional},{array,"of items"}}`: []token{{typ: tokenArrayStart, val: "{"}, {typ: tokenArrayStart, val: "{"}, {typ: tokenString, val: "two"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "dimensional"}, {typ: tokenArrayEnd, val: "}"}, {typ: tokenSeparator, val: ","}, {typ: tokenArrayStart, val: "{"}, {typ: tokenString, val: "array"}, {typ: tokenSeparator, val: ","}, {typ: tokenString, val: "of items"}, {typ: tokenArrayEnd, val: "}"}, {typ: tokenArrayEnd, val: "}"}},
    1.18 +}
    1.19 +
    1.20 +func TestInputsTable(t *testing.T) {
    1.21 +	for input, expectedTokens := range testInputs {
    1.22 +		l := lex(input)
    1.23 +		var tokens []token
    1.24 +		for {
    1.25 +			tok := l.nextToken()
    1.26 +			if tok.typ == tokenEOF {
    1.27 +				break
    1.28 +			}
    1.29 +			tokens = append(tokens, tok)
    1.30 +			if tok.typ == tokenError {
    1.31 +				break
    1.32 +			}
    1.33 +		}
    1.34 +		t.Logf("%#+v\n", tokens)
    1.35 +		if len(tokens) != len(expectedTokens) {
    1.36 +			t.Fatalf("Expected %d tokens, got %d\n", len(expectedTokens), len(tokens))
    1.37 +		}
    1.38 +		for pos, tok := range tokens {
    1.39 +			if expectedTokens[pos].typ != tok.typ {
    1.40 +				t.Errorf("Expected token in pos %d to have type of %s, got %s instead.", pos, expectedTokens[pos].typ, tok.typ)
    1.41 +			}
    1.42 +			if expectedTokens[pos].val != tok.val {
    1.43 +				t.Errorf("Expected token in pos %d to have value of `%s`, got `%s` instead.", pos, expectedTokens[pos].val, tok.val)
    1.44 +			}
    1.45 +		}
    1.46 +	}
    1.47 +}