2019-03-24 14:57:29 +01:00
|
|
|
package qcode
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"testing"
|
2020-06-05 03:55:52 +02:00
|
|
|
|
|
|
|
"github.com/chirino/graphql/schema"
|
2019-03-24 14:57:29 +01:00
|
|
|
)
|
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
func TestCompile1(t *testing.T) {
|
2019-10-14 08:51:36 +02:00
|
|
|
qc, _ := NewCompiler(Config{})
|
2019-11-28 07:25:46 +01:00
|
|
|
err := qc.AddRole("user", "product", TRConfig{
|
2019-10-14 08:51:36 +02:00
|
|
|
Query: QueryConfig{
|
|
|
|
Columns: []string{"id", "Name"},
|
|
|
|
},
|
|
|
|
})
|
2019-11-28 07:25:46 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2019-06-15 04:17:21 +02:00
|
|
|
|
2019-11-28 07:25:46 +01:00
|
|
|
_, err = qc.Compile([]byte(`
|
2020-01-16 07:44:19 +01:00
|
|
|
query { product(id: 15) {
|
2019-04-20 16:45:12 +02:00
|
|
|
id
|
|
|
|
name
|
2019-11-19 06:47:55 +01:00
|
|
|
} }`), "user")
|
2019-06-15 04:17:21 +02:00
|
|
|
|
2020-02-19 05:52:44 +01:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal(errors.New("this should be an error id must be a variable"))
|
2019-04-20 16:45:12 +02:00
|
|
|
}
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
2019-04-20 23:27:03 +02:00
|
|
|
|
2019-09-05 06:09:56 +02:00
|
|
|
func TestCompile2(t *testing.T) {
|
2019-10-14 08:51:36 +02:00
|
|
|
qc, _ := NewCompiler(Config{})
|
2019-11-28 07:25:46 +01:00
|
|
|
err := qc.AddRole("user", "product", TRConfig{
|
2019-10-14 08:51:36 +02:00
|
|
|
Query: QueryConfig{
|
|
|
|
Columns: []string{"ID"},
|
|
|
|
},
|
|
|
|
})
|
2019-11-28 07:25:46 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2019-09-05 06:09:56 +02:00
|
|
|
|
2019-11-28 07:25:46 +01:00
|
|
|
_, err = qc.Compile([]byte(`
|
2020-02-19 05:52:44 +01:00
|
|
|
query { product(id: $id) {
|
2019-09-05 06:09:56 +02:00
|
|
|
id
|
|
|
|
name
|
2019-10-14 08:51:36 +02:00
|
|
|
} }`), "user")
|
2019-09-05 06:09:56 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCompile3(t *testing.T) {
|
2019-10-14 08:51:36 +02:00
|
|
|
qc, _ := NewCompiler(Config{})
|
2019-11-28 07:25:46 +01:00
|
|
|
err := qc.AddRole("user", "product", TRConfig{
|
2019-10-14 08:51:36 +02:00
|
|
|
Query: QueryConfig{
|
|
|
|
Columns: []string{"ID"},
|
|
|
|
},
|
|
|
|
})
|
2019-11-28 07:25:46 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2019-09-05 06:09:56 +02:00
|
|
|
|
2019-11-28 07:25:46 +01:00
|
|
|
_, err = qc.Compile([]byte(`
|
2019-09-05 06:09:56 +02:00
|
|
|
mutation {
|
2020-02-19 05:52:44 +01:00
|
|
|
product(id: $test, name: "Test") {
|
2019-09-05 06:09:56 +02:00
|
|
|
id
|
|
|
|
name
|
|
|
|
}
|
2019-10-14 08:51:36 +02:00
|
|
|
}`), "user")
|
2019-09-05 06:09:56 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-16 21:41:28 +02:00
|
|
|
func TestInvalidCompile1(t *testing.T) {
|
2019-04-21 01:42:08 +02:00
|
|
|
qcompile, _ := NewCompiler(Config{})
|
2019-10-14 08:51:36 +02:00
|
|
|
_, err := qcompile.Compile([]byte(`#`), "user")
|
2019-06-15 04:17:21 +02:00
|
|
|
|
2019-04-21 01:42:08 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal(errors.New("expecting an error"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-16 21:41:28 +02:00
|
|
|
func TestInvalidCompile2(t *testing.T) {
|
|
|
|
qcompile, _ := NewCompiler(Config{})
|
2019-10-14 08:51:36 +02:00
|
|
|
_, err := qcompile.Compile([]byte(`{u(where:{not:0})}`), "user")
|
2019-06-16 21:41:28 +02:00
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal(errors.New("expecting an error"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-20 23:27:03 +02:00
|
|
|
func TestEmptyCompile(t *testing.T) {
|
|
|
|
qcompile, _ := NewCompiler(Config{})
|
2019-10-14 08:51:36 +02:00
|
|
|
_, err := qcompile.Compile([]byte(``), "user")
|
2019-06-15 04:17:21 +02:00
|
|
|
|
2019-04-20 23:27:03 +02:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal(errors.New("expecting an error"))
|
|
|
|
}
|
|
|
|
}
|
2019-05-15 04:32:12 +02:00
|
|
|
|
2020-01-16 07:44:19 +01:00
|
|
|
func TestInvalidPostfixCompile(t *testing.T) {
|
|
|
|
gql := `mutation
|
|
|
|
updateThread {
|
|
|
|
thread(update: $data, where: { slug: { eq: $slug } }) {
|
|
|
|
slug
|
|
|
|
title
|
|
|
|
published
|
|
|
|
createdAt : created_at
|
|
|
|
totalVotes : cached_votes_total
|
|
|
|
totalPosts : cached_posts_total
|
|
|
|
vote : thread_vote(where: { user_id: { eq: $user_id } }) {
|
|
|
|
id
|
|
|
|
}
|
|
|
|
topics {
|
|
|
|
slug
|
|
|
|
name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-06-06 23:52:21 +02:00
|
|
|
}}`
|
2020-01-16 07:44:19 +01:00
|
|
|
qcompile, _ := NewCompiler(Config{})
|
|
|
|
_, err := qcompile.Compile([]byte(gql), "anon")
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
t.Fatal(errors.New("expecting an error"))
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-06-06 23:52:21 +02:00
|
|
|
func TestFragmentsCompile1(t *testing.T) {
|
2020-06-05 03:55:52 +02:00
|
|
|
gql := `
|
2020-06-06 23:52:21 +02:00
|
|
|
fragment userFields1 on user {
|
|
|
|
id
|
|
|
|
email
|
|
|
|
}
|
|
|
|
|
|
|
|
query {
|
|
|
|
users {
|
|
|
|
...userFields2
|
|
|
|
|
|
|
|
created_at
|
|
|
|
...userFields1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fragment userFields2 on user {
|
|
|
|
first_name
|
|
|
|
last_name
|
|
|
|
}
|
|
|
|
`
|
|
|
|
qcompile, _ := NewCompiler(Config{})
|
|
|
|
_, err := qcompile.Compile([]byte(gql), "user")
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-06-05 03:55:52 +02:00
|
|
|
}
|
2020-06-06 23:52:21 +02:00
|
|
|
|
|
|
|
func TestFragmentsCompile2(t *testing.T) {
|
|
|
|
gql := `
|
|
|
|
query {
|
|
|
|
users {
|
|
|
|
...userFields2
|
2020-06-05 03:55:52 +02:00
|
|
|
|
2020-06-06 23:52:21 +02:00
|
|
|
created_at
|
|
|
|
...userFields1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fragment userFields1 on user {
|
|
|
|
id
|
|
|
|
email
|
|
|
|
}
|
|
|
|
|
|
|
|
fragment userFields2 on user {
|
|
|
|
first_name
|
|
|
|
last_name
|
|
|
|
}`
|
2020-06-05 03:55:52 +02:00
|
|
|
qcompile, _ := NewCompiler(Config{})
|
2020-06-06 23:52:21 +02:00
|
|
|
_, err := qcompile.Compile([]byte(gql), "user")
|
2020-06-05 03:55:52 +02:00
|
|
|
|
2020-06-06 23:52:21 +02:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFragmentsCompile3(t *testing.T) {
|
|
|
|
gql := `
|
|
|
|
fragment userFields1 on user {
|
|
|
|
id
|
|
|
|
email
|
|
|
|
}
|
|
|
|
|
|
|
|
fragment userFields2 on user {
|
|
|
|
first_name
|
|
|
|
last_name
|
|
|
|
}
|
|
|
|
|
|
|
|
query {
|
|
|
|
users {
|
|
|
|
...userFields2
|
|
|
|
|
|
|
|
created_at
|
|
|
|
...userFields1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
`
|
|
|
|
qcompile, _ := NewCompiler(Config{})
|
|
|
|
_, err := qcompile.Compile([]byte(gql), "user")
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
2020-06-05 03:55:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-15 04:17:21 +02:00
|
|
|
var gql = []byte(`
|
2020-05-07 16:48:01 +02:00
|
|
|
{products(
|
2019-06-01 08:03:09 +02:00
|
|
|
# returns only 30 items
|
|
|
|
limit: 30,
|
|
|
|
|
|
|
|
# starts from item 10, commented out for now
|
|
|
|
# offset: 10,
|
|
|
|
|
|
|
|
# orders the response items by highest price
|
|
|
|
order_by: { price: desc },
|
|
|
|
|
|
|
|
# no duplicate prices returned
|
|
|
|
distinct: [ price ]
|
|
|
|
|
|
|
|
# only items with an id >= 30 and < 30 are returned
|
|
|
|
where: { id: { AND: { greater_or_equals: 20, lt: 28 } } }) {
|
|
|
|
id
|
|
|
|
name
|
|
|
|
price
|
2020-05-07 16:48:01 +02:00
|
|
|
}}`)
|
2019-06-01 08:03:09 +02:00
|
|
|
|
2020-06-07 19:02:57 +02:00
|
|
|
var gqlWithFragments = []byte(`
|
|
|
|
fragment userFields1 on user {
|
|
|
|
id
|
|
|
|
email
|
|
|
|
__typename
|
|
|
|
}
|
|
|
|
|
|
|
|
query {
|
|
|
|
users {
|
|
|
|
...userFields2
|
|
|
|
|
|
|
|
created_at
|
|
|
|
...userFields1
|
|
|
|
__typename
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fragment userFields2 on user {
|
|
|
|
first_name
|
|
|
|
last_name
|
|
|
|
__typename
|
|
|
|
}`)
|
|
|
|
|
2019-05-15 04:32:12 +02:00
|
|
|
func BenchmarkQCompile(b *testing.B) {
|
|
|
|
qcompile, _ := NewCompiler(Config{})
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
2019-10-14 08:51:36 +02:00
|
|
|
_, err := qcompile.Compile(gql, "user")
|
2019-05-15 04:32:12 +02:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-01 08:03:09 +02:00
|
|
|
func BenchmarkQCompileP(b *testing.B) {
|
|
|
|
qcompile, _ := NewCompiler(Config{})
|
2019-05-15 04:32:12 +02:00
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
2019-06-01 08:03:09 +02:00
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
2019-10-14 08:51:36 +02:00
|
|
|
_, err := qcompile.Compile(gql, "user")
|
2019-05-15 04:32:12 +02:00
|
|
|
|
2019-06-01 08:03:09 +02:00
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
2019-05-15 04:32:12 +02:00
|
|
|
}
|
2019-06-01 08:03:09 +02:00
|
|
|
})
|
2019-05-15 04:32:12 +02:00
|
|
|
}
|
2020-05-07 16:48:01 +02:00
|
|
|
|
2020-06-07 19:02:57 +02:00
|
|
|
func BenchmarkQCompileFragment(b *testing.B) {
|
|
|
|
qcompile, _ := NewCompiler(Config{})
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
_, err := qcompile.Compile(gqlWithFragments, "user")
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-05-07 16:48:01 +02:00
|
|
|
func BenchmarkParse(b *testing.B) {
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
_, err := Parse(gql)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkParseP(b *testing.B) {
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
|
|
|
_, err := Parse(gql)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-06-07 19:02:57 +02:00
|
|
|
func BenchmarkParseFragment(b *testing.B) {
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
_, err := Parse(gqlWithFragments)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-07 16:48:01 +02:00
|
|
|
func BenchmarkSchemaParse(b *testing.B) {
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
doc := schema.QueryDocument{}
|
|
|
|
err := doc.Parse(string(gql))
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkSchemaParseP(b *testing.B) {
|
|
|
|
b.ResetTimer()
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
|
|
|
doc := schema.QueryDocument{}
|
|
|
|
err := doc.Parse(string(gql))
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|