func TestOrderDescending(t *testing.T) { stubSource := NewStubSource(testData) order := NewOrder([]*ast.SortExpression{ast.NewSortExpression(ast.NewProperty("age"), false)}, []string{}) order.SetSource(stubSource) orderItemChannel, _ := order.GetChannels() stopChannel := make(misc.StopChannel) go order.Run(stopChannel) count := 0 for item := range orderItemChannel { val, err := item.Path("name") if err != nil { t.Errorf("unexpected error: %v", err) } value := val.Value() if count == 0 && value != "steve" { t.Errorf("expected steve, got %v", value) } if count == len(testData)-1 && value != "dustin" { t.Errorf("expected dustin, got %v", value) } count++ } }
func TestParserASTOutput(t *testing.T) { tests := []struct { input string output ast.Statement }{ {"SELECT * FROM test WHERE true", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: ast.NewLiteralBool(true), Limit: -1, }, }, {"SELECT * FROM :apool.test WHERE true", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Pool: "apool", Projection: ast.NewProperty("test")}, Where: ast.NewLiteralBool(true), Limit: -1, }, }, {"SELECT * FROM test ORDER BY foo", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: nil, OrderBy: []*ast.SortExpression{ ast.NewSortExpression(ast.NewProperty("foo"), true), }, Limit: -1, }, }, {"SELECT * FROM test LIMIT 10 OFFSET 3", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewStarResultExpression(), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: nil, Limit: 10, Offset: 3, }, }, {"SELECT a FROM test", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpression(ast.NewProperty("a")), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test")}, Where: nil, Limit: -1, }, }, {"SELECT a FROM test t2", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpression(ast.NewProperty("a")), }, Distinct: false, From: &ast.From{Projection: ast.NewProperty("test"), As: "t2"}, Where: nil, Limit: -1, }, }, {"SELECT 1+1*30 as steve", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"), }, Distinct: false, From: nil, Where: nil, Limit: -1, }, }, {"SELECT 1+1*30 steve", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"), }, Distinct: false, From: nil, Where: nil, Limit: -1, }, }, {"SELECT DISTINCT 1+1*30 as steve", &ast.SelectStatement{ Select: ast.ResultExpressionList{ ast.NewResultExpressionWithAlias(ast.NewPlusOperator(ast.NewLiteralNumber(1.0), ast.NewMultiplyOperator(ast.NewLiteralNumber(1.0), ast.NewLiteralNumber(30.0))), "steve"), }, Distinct: true, From: nil, Where: nil, Limit: -1, }, }, {"CREATE INDEX abv_idx ON beer-sample(abv) USING VIEW", &ast.CreateIndexStatement{ Method: "view", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON beer-sample(abv) USING magic", &ast.CreateIndexStatement{ Method: "magic", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON beer-sample(abv)", &ast.CreateIndexStatement{ Method: "", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON :apool.beer-sample(abv) USING VIEW", &ast.CreateIndexStatement{ Method: "view", Pool: "apool", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON :apool.beer-sample(abv) USING magic", &ast.CreateIndexStatement{ Method: "magic", Pool: "apool", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"CREATE INDEX abv_idx ON :apool.beer-sample(abv)", &ast.CreateIndexStatement{ Method: "", Pool: "apool", Bucket: "beer-sample", Name: "abv_idx", On: ast.ExpressionList{ast.NewProperty("abv")}, }, }, {"DROP INDEX beer-sample.abv", &ast.DropIndexStatement{ Bucket: "beer-sample", Name: "abv", }, }, {"DROP INDEX :apool.beer-sample.abv", &ast.DropIndexStatement{ Pool: "apool", Bucket: "beer-sample", Name: "abv", }, }, } n1qlParser := NewN1qlParser() for _, v := range tests { query, err := n1qlParser.Parse(v.input) if err != nil { t.Errorf("Valid Query Parse Failed: %v - %v", v, err) } if !reflect.DeepEqual(query, v.output) { t.Errorf("Expected %v, got %v", v.output, query) js, err := json.MarshalIndent(v.output, "", " ") if err == nil { t.Logf("Expected %v", string(js)) } js, err = json.MarshalIndent(query, "", " ") if err == nil { t.Logf("Got %v", string(js)) } } } }