func TestAttachedComments(t *testing.T) { var q = `//Unattached root = a.b //attached a.b = start /*attached*/ start c = accept /*attached*/start _ = start /*unattached*/ start d = accept` p := parser.NewParser() rules, err := p.ParseRules(lexer.NewLexer([]byte(q))) if err != nil { t.Fatalf(err.Error()) } count := 0 for _, rule := range rules.Rules { c := rule.GetAttachedComment().GetContent() if len(c) > 0 { if c != "attached" { t.Fatalf("received attached comment = %s", c) } else { count++ } } } if count != 3 { t.Fatalf("did not find enough attached comments") } }
func Uint32ToGo(s string) (uint32, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return 0, err } if expr.Terminal == nil { return 0, &ErrWrongType{"uint32", "not a terminal"} } return uint32ToGo(expr.GetTerminal()) }
func DoubleToGo(s string) (float64, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return 0, err } if expr.Terminal == nil { return 0, &ErrWrongType{"double", "not a terminal"} } return doubleToGo(expr.GetTerminal()) }
func BytesToGo(s string) ([]byte, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return nil, err } if expr.Terminal == nil { return nil, &ErrWrongType{"[]byte", "not a terminal"} } return bytesToGo(expr.GetTerminal()) }
func StringToGo(s string) (string, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return "", err } if expr.Terminal == nil { return "", &ErrWrongType{"string", "not a terminal"} } return stringToGo(expr.GetTerminal()) }
func BoolToGo(s string) (bool, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return false, err } if expr.Terminal == nil { return false, &ErrWrongType{"bool", "not a terminal"} } return boolToGo(expr.GetTerminal()) }
func FloatsToGo(s string) ([]float32, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return nil, err } if expr.List == nil { return nil, &ErrWrongType{"[]float", "not a list"} } list := expr.GetList() elems := list.GetElems() if list.GetType() != types.LIST_FLOAT { return nil, &ErrWrongType{"[]float", list.GetType().String()} } return floatsToGo(elems) }
func ListOfBytesToGo(s string) ([][]byte, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return nil, err } if expr.List == nil { return nil, &ErrWrongType{"[][]byte", "not a list"} } list := expr.GetList() elems := list.GetElems() if list.GetType() != types.LIST_BYTES { return nil, &ErrWrongType{"[][]byte", list.GetType().String()} } return listOfBytesToGo(elems) }
func Uint64sToGo(s string) ([]uint64, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return nil, err } if expr.List == nil { return nil, &ErrWrongType{"[]uint64", "not a list"} } list := expr.GetList() elems := list.GetElems() if list.GetType() != types.LIST_UINT64 { return nil, &ErrWrongType{"[]uint64", list.GetType().String()} } return uint64sToGo(elems) }
func TestCompileError(t *testing.T) { fileDescriptorSet, err := protoparser.ParseFile("person.proto", ".", gogoprotoImportPath) if err != nil { panic(err) } p := parser.NewParser() rules, err := p.ParseRules(lexer.NewLexer([]byte(compileErr))) if err != nil { t.Fatalf(err.Error()) } protoTokens, err := tokens.NewZipped(rules, fileDescriptorSet) if err != nil { panic(err) } _, _, err = compiler.Compile(rules, protoTokens) if err == nil { t.Fatalf("expected error") } }
func TestInject(t *testing.T) { fileDescriptorSet, err := protoparser.ParseFile("person.proto", ".", gogoprotoImportPath) if err != nil { panic(err) } p := parser.NewParser() rules, err := p.ParseRules(lexer.NewLexer([]byte(injectPerson))) if err != nil { t.Fatalf(err.Error()) } protoTokens, err := tokens.NewZipped(rules, fileDescriptorSet) if err != nil { panic(err) } e, rootToken, err := compiler.Compile(rules, protoTokens) if err != nil { panic(err) } typ := reflect.TypeOf((*InjectableInt64)(nil)).Elem() instances := inject.Implements(e, typ) for _, instance := range instances { instance.(InjectableInt64).SetValue(456) } m := robert data, err := proto.Marshal(m) if err != nil { panic(err) } s := scanner.NewProtoScanner(protoTokens, rootToken) err = s.Init(data) if err != nil { panic(err) } match, err := e.Eval(s) if err != nil { panic(err) } if !match { t.Fatalf("expected match") } }
func newBench(protoFilename string, katydidStr string) bench { fileDescriptorSet, err := protoparser.ParseFile(protoFilename, ".", gogoprotoImportPath) if err != nil { panic(err) } p := parser.NewParser() rules, err := p.ParseRules(lexer.NewLexer([]byte(katydidStr))) if err != nil { panic(err) } protoTokens, err := tokens.NewZipped(rules, fileDescriptorSet) if err != nil { panic(err) } e, rootToken, err := compiler.Compile(rules, protoTokens) if err != nil { panic(err) } return bench{ exec: e, scanner: scanner.NewProtoScanner(protoTokens, rootToken), } }
func TestRuntimeError(t *testing.T) { fileDescriptorSet, err := protoparser.ParseFile("person.proto", ".", gogoprotoImportPath) if err != nil { panic(err) } p := parser.NewParser() rules, err := p.ParseRules(lexer.NewLexer([]byte(runtimeErr))) if err != nil { t.Fatalf(err.Error()) } protoTokens, err := tokens.NewZipped(rules, fileDescriptorSet) if err != nil { panic(err) } e, rootToken, err := compiler.Compile(rules, protoTokens) if err != nil { panic(err) } m := robert data, err := proto.Marshal(m) if err != nil { panic(err) } s := scanner.NewProtoScanner(protoTokens, rootToken) err = s.Init(data) if err != nil { panic(err) } match, err := e.Eval(s) if err == nil { t.Fatalf("expected error") } if match { t.Fatalf("expected match") } }
func example(t *testing.T, protoFilename string, m proto.Message, katydidStr string, positive bool) { name := exampleName() test(t, protoFilename, m, katydidStr, positive) dir := exampleDir(name) dotFilename := filepath.Join(dir, name+".dot") pdfFilename := filepath.Join(dir, name+".pdf") txtFilename := filepath.Join(dir, name+".txt") oneFilename := filepath.Join(dir, "one.box") twoFilename := filepath.Join(dir, "two.box") threeFilename := filepath.Join(dir, "three.box") jsonFilename := filepath.Join(dir, name+".json") if err := ioutil.WriteFile(txtFilename, []byte(katydidStr), 0666); err != nil { panic(err) } p := parser.NewParser() rules, err := p.ParseRules(lexer.NewLexer([]byte(katydidStr))) if err != nil { t.Fatalf(err.Error()) } dotString := rules.Dot() if err := ioutil.WriteFile(dotFilename, []byte(dotString), 0666); err != nil { panic(err) } cmd := exec.Command("dot", dotFilename, "-Tpdf", "-o", pdfFilename) output, err := cmd.CombinedOutput() if err != nil { t.Fatalf("dot error: " + err.Error() + ":" + string(output)) } protoBytes, err := ioutil.ReadFile(protoFilename) if err != nil { panic(err) } if err := ioutil.WriteFile(oneFilename, protoBytes, 0666); err != nil { panic(err) } jsonBytes, err := json.MarshalIndent(m, "", " ") if err != nil { panic(err) } if err := ioutil.WriteFile(jsonFilename, jsonBytes, 0666); err != nil { panic(err) } fulltyp := fmt.Sprintf("%T", m) typ := strings.Replace(fulltyp, "main.", "", -1) newtyp := strings.Replace(typ, "*", "&", -1) popStr := `package main import ( "encoding/json" ) func Populate() (` + typ + `, error) { m := ` + newtyp + `{} jsonValue := ` + "`" + string(jsonBytes) + "`" + ` if err := json.Unmarshal([]byte(jsonValue), m); err != nil { panic(err) } return m, nil } ` if err := ioutil.WriteFile(twoFilename, []byte(popStr), 0666); err != nil { panic(err) } if err := ioutil.WriteFile(threeFilename, []byte(katydidStr), 0666); err != nil { panic(err) } }
func test(t *testing.T, protoFilename string, m proto.Message, katydidStr string, positive bool) { fileDescriptorSet, err := protoparser.ParseFile(protoFilename, ".", gogoprotoImportPath) if err != nil { panic(err) } p := parser.NewParser() rules, err := p.ParseRules(lexer.NewLexer([]byte(katydidStr))) if err != nil { t.Fatalf(err.Error()) } outputStr := rules.String() if katydidStr != outputStr { t.Logf("input = <<%s>>", katydidStr) t.Logf("output = <<%s>>", outputStr) t.Fatalf("Parsed string should output same string from ast") } //Testing Query on Protocol Buffer Marshaled Structures protoTokens, err := tokens.NewZipped(rules, fileDescriptorSet) if err != nil { panic(err) } e, rootToken, err := compiler.Compile(rules, protoTokens) if err != nil { panic(err) } data, err := proto.Marshal(m) if err != nil { panic(err) } s := scanner.NewProtoScanner(protoTokens, rootToken) err = s.Init(data) if err != nil { panic(err) } if match, err := e.Eval(s); err != nil { t.Errorf("Error: %v", err) } else if match != positive { t.Errorf("Expected a %v match from \n%v \non \n%v", positive, katydidStr, m) } //Testing Query on Json Marshaled Structures jsonTokens, err := jsontokens.NewZipped(rules, fileDescriptorSet) if err != nil { panic(err) } e, rootToken, err = compiler.Compile(rules, jsonTokens) if err != nil { panic(err) } jsonData, err := json.Marshal(m) if err != nil { panic(err) } jsonS := jsonscanner.NewScanner(jsonTokens, rootToken) err = jsonS.Init(jsonData) if err != nil { panic(err) } if match, err := e.Eval(jsonS); err != nil { t.Errorf("Error: %v", err) } else if match != positive { t.Errorf("Expected a %v match from \n%v \non \n%v", positive, katydidStr, m) } //Testing Query on Reflected Structures e, rootToken, err = compiler.Compile(rules, jsonTokens) if err != nil { panic(err) } if match, err := e.Eval(reflectscanner.NewScanner(jsonTokens, rootToken).Init(reflect.ValueOf(m))); err != nil { t.Errorf("Error: %v", err) } else if match != positive { t.Errorf("Expected a %v match from \n%v \non \n%v", positive, katydidStr, m) } }
func ToGo(s string) (interface{}, error) { expr, err := parser.NewParser().ParseExpr(lexer.NewLexer([]byte(s))) if err != nil { return nil, err } if expr.List == nil { if expr.Terminal == nil { return nil, &ErrUnknownType{expr.String()} } term := expr.GetTerminal() if term.DoubleValue != nil { return doubleToGo(term) } if term.FloatValue != nil { return floatToGo(term) } if term.Int64Value != nil { return int64ToGo(term) } if term.Uint64Value != nil { return uint64ToGo(term) } if term.Int32Value != nil { return int32ToGo(term) } if term.BoolValue != nil { return boolToGo(term) } if term.StringValue != nil { return stringToGo(term) } if term.BytesValue != nil { return bytesToGo(term) } if term.Uint32Value != nil { return uint32ToGo(term) } return nil, &ErrUnknownType{expr.String()} } list := expr.GetList() elems := list.GetElems() switch list.GetType() { case types.LIST_DOUBLE: return doublesToGo(elems) case types.LIST_FLOAT: return floatsToGo(elems) case types.LIST_INT64: return int64sToGo(elems) case types.LIST_UINT64: return uint64sToGo(elems) case types.LIST_INT32: return int32sToGo(elems) case types.LIST_BOOL: return boolsToGo(elems) case types.LIST_STRING: return stringsToGo(elems) case types.LIST_BYTES: return listOfBytesToGo(elems) case types.LIST_UINT32: return uint32sToGo(elems) } return nil, &ErrUnknownType{expr.String()} }