| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- // +build go1.7
- package ini
- import (
- "bytes"
- "fmt"
- "io"
- "reflect"
- "testing"
- )
- func TestParser(t *testing.T) {
- xID, _, _ := newLitToken([]rune("x = 1234"))
- s3ID, _, _ := newLitToken([]rune("s3 = 1234"))
- fooSlashes, _, _ := newLitToken([]rune("//foo"))
- regionID, _, _ := newLitToken([]rune("region"))
- regionLit, _, _ := newLitToken([]rune(`"us-west-2"`))
- regionNoQuotesLit, _, _ := newLitToken([]rune("us-west-2"))
- credentialID, _, _ := newLitToken([]rune("credential_source"))
- ec2MetadataLit, _, _ := newLitToken([]rune("Ec2InstanceMetadata"))
- outputID, _, _ := newLitToken([]rune("output"))
- outputLit, _, _ := newLitToken([]rune("json"))
- equalOp, _, _ := newOpToken([]rune("= 1234"))
- equalColonOp, _, _ := newOpToken([]rune(": 1234"))
- numLit, _, _ := newLitToken([]rune("1234"))
- defaultID, _, _ := newLitToken([]rune("default"))
- assumeID, _, _ := newLitToken([]rune("assumerole"))
- defaultProfileStmt := newSectionStatement(defaultID)
- assumeProfileStmt := newSectionStatement(assumeID)
- fooSlashesExpr := newExpression(fooSlashes)
- xEQ1234 := newEqualExpr(newExpression(xID), equalOp)
- xEQ1234.AppendChild(newExpression(numLit))
- xEQColon1234 := newEqualExpr(newExpression(xID), equalColonOp)
- xEQColon1234.AppendChild(newExpression(numLit))
- regionEQRegion := newEqualExpr(newExpression(regionID), equalOp)
- regionEQRegion.AppendChild(newExpression(regionLit))
- noQuotesRegionEQRegion := newEqualExpr(newExpression(regionID), equalOp)
- noQuotesRegionEQRegion.AppendChild(newExpression(regionNoQuotesLit))
- credEQExpr := newEqualExpr(newExpression(credentialID), equalOp)
- credEQExpr.AppendChild(newExpression(ec2MetadataLit))
- outputEQExpr := newEqualExpr(newExpression(outputID), equalOp)
- outputEQExpr.AppendChild(newExpression(outputLit))
- cases := []struct {
- name string
- r io.Reader
- expectedStack []AST
- expectedError bool
- }{
- {
- name: "semicolon comment",
- r: bytes.NewBuffer([]byte(`;foo`)),
- expectedStack: []AST{
- newCommentStatement(newToken(TokenComment, []rune(";foo"), NoneType)),
- },
- },
- {
- name: "0==0",
- r: bytes.NewBuffer([]byte(`0==0`)),
- expectedError: true,
- },
- {
- name: "0=:0",
- r: bytes.NewBuffer([]byte(`0=:0`)),
- expectedError: true,
- },
- {
- name: "0:=0",
- r: bytes.NewBuffer([]byte(`0:=0`)),
- expectedError: true,
- },
- {
- name: "0::0",
- r: bytes.NewBuffer([]byte(`0::0`)),
- expectedError: true,
- },
- {
- name: "section with variable",
- r: bytes.NewBuffer([]byte(`[ default ]x`)),
- expectedStack: []AST{
- newCompletedSectionStatement(
- defaultProfileStmt,
- ),
- newExpression(xID),
- },
- },
- {
- name: "# comment",
- r: bytes.NewBuffer([]byte(`# foo`)),
- expectedStack: []AST{
- newCommentStatement(newToken(TokenComment, []rune("# foo"), NoneType)),
- },
- },
- {
- name: "// not a comment",
- r: bytes.NewBuffer([]byte(`//foo`)),
- expectedStack: []AST{
- fooSlashesExpr,
- },
- },
- {
- name: "multiple comments",
- r: bytes.NewBuffer([]byte(`;foo
- # baz
- `)),
- expectedStack: []AST{
- newCommentStatement(newToken(TokenComment, []rune(";foo"), NoneType)),
- newCommentStatement(newToken(TokenComment, []rune("# baz"), NoneType)),
- },
- },
- {
- name: "comment followed by skip state",
- r: bytes.NewBuffer([]byte(`;foo
- //foo
- # baz
- `)),
- expectedStack: []AST{
- newCommentStatement(newToken(TokenComment, []rune(";foo"), NoneType)),
- },
- },
- {
- name: "assignment",
- r: bytes.NewBuffer([]byte(`x = 1234`)),
- expectedStack: []AST{
- newExprStatement(xEQ1234),
- },
- },
- {
- name: "assignment spaceless",
- r: bytes.NewBuffer([]byte(`x=1234`)),
- expectedStack: []AST{
- newExprStatement(xEQ1234),
- },
- },
- {
- name: "assignment :",
- r: bytes.NewBuffer([]byte(`x : 1234`)),
- expectedStack: []AST{
- newExprStatement(xEQColon1234),
- },
- },
- {
- name: "assignment : no spaces",
- r: bytes.NewBuffer([]byte(`x:1234`)),
- expectedStack: []AST{
- newExprStatement(xEQColon1234),
- },
- },
- {
- name: "section expression",
- r: bytes.NewBuffer([]byte(`[ default ]`)),
- expectedStack: []AST{
- newCompletedSectionStatement(
- defaultProfileStmt,
- ),
- },
- },
- {
- name: "section expression no spaces",
- r: bytes.NewBuffer([]byte(`[default]`)),
- expectedStack: []AST{
- newCompletedSectionStatement(
- defaultProfileStmt,
- ),
- },
- },
- {
- name: "section statement",
- r: bytes.NewBuffer([]byte(`[default]
- region="us-west-2"`)),
- expectedStack: []AST{
- newCompletedSectionStatement(
- defaultProfileStmt,
- ),
- newExprStatement(regionEQRegion),
- },
- },
- {
- name: "complex section statement",
- r: bytes.NewBuffer([]byte(`[default]
- region = us-west-2
- credential_source = Ec2InstanceMetadata
- output = json
- [assumerole]
- output = json
- region = us-west-2
- `)),
- expectedStack: []AST{
- newCompletedSectionStatement(
- defaultProfileStmt,
- ),
- newExprStatement(noQuotesRegionEQRegion),
- newExprStatement(credEQExpr),
- newExprStatement(outputEQExpr),
- newCompletedSectionStatement(
- assumeProfileStmt,
- ),
- newExprStatement(outputEQExpr),
- newExprStatement(noQuotesRegionEQRegion),
- },
- },
- {
- name: "complex section statement with nested params",
- r: bytes.NewBuffer([]byte(`[default]
- s3 =
- foo=bar
- bar=baz
- region = us-west-2
- credential_source = Ec2InstanceMetadata
- output = json
- [assumerole]
- output = json
- region = us-west-2
- `)),
- expectedStack: []AST{
- newCompletedSectionStatement(
- defaultProfileStmt,
- ),
- newSkipStatement(newEqualExpr(newExpression(s3ID), equalOp)),
- newExprStatement(noQuotesRegionEQRegion),
- newExprStatement(credEQExpr),
- newExprStatement(outputEQExpr),
- newCompletedSectionStatement(
- assumeProfileStmt,
- ),
- newExprStatement(outputEQExpr),
- newExprStatement(noQuotesRegionEQRegion),
- },
- },
- {
- name: "complex section statement",
- r: bytes.NewBuffer([]byte(`[default]
- region = us-west-2
- credential_source = Ec2InstanceMetadata
- s3 =
- foo=bar
- bar=baz
- output = json
- [assumerole]
- output = json
- region = us-west-2
- `)),
- expectedStack: []AST{
- newCompletedSectionStatement(
- defaultProfileStmt,
- ),
- newExprStatement(noQuotesRegionEQRegion),
- newExprStatement(credEQExpr),
- newSkipStatement(newEqualExpr(newExpression(s3ID), equalOp)),
- newExprStatement(outputEQExpr),
- newCompletedSectionStatement(
- assumeProfileStmt,
- ),
- newExprStatement(outputEQExpr),
- newExprStatement(noQuotesRegionEQRegion),
- },
- },
- }
- for i, c := range cases {
- t.Run(c.name, func(t *testing.T) {
- stack, err := ParseAST(c.r)
- if e, a := c.expectedError, err != nil; e != a {
- t.Errorf("%d: expected %t, but received %t with error %v", i, e, a, err)
- }
- if e, a := len(c.expectedStack), len(stack); e != a {
- t.Errorf("expected same length %d, but received %d", e, a)
- }
- if e, a := c.expectedStack, stack; !reflect.DeepEqual(e, a) {
- buf := bytes.Buffer{}
- buf.WriteString("expected:\n")
- for j := 0; j < len(e); j++ {
- buf.WriteString(fmt.Sprintf("\t%d: %v\n", j, e[j]))
- }
- buf.WriteString("\nreceived:\n")
- for j := 0; j < len(a); j++ {
- buf.WriteString(fmt.Sprintf("\t%d: %v\n", j, a[j]))
- }
- t.Errorf("%s", buf.String())
- }
- })
- }
- }
|