github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/schema/parse_test.go (about)

     1  /*
     2   * Copyright 2016-2018 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package schema
    18  
    19  import (
    20  	"io/ioutil"
    21  	"os"
    22  	"testing"
    23  
    24  	"github.com/dgraph-io/badger"
    25  	"github.com/stretchr/testify/require"
    26  
    27  	"github.com/dgraph-io/dgraph/protos/pb"
    28  	"github.com/dgraph-io/dgraph/types"
    29  	"github.com/dgraph-io/dgraph/x"
    30  )
    31  
    32  type nameType struct {
    33  	name string
    34  	typ  *pb.SchemaUpdate
    35  }
    36  
    37  func checkSchema(t *testing.T, h map[string]*pb.SchemaUpdate, expected []nameType) {
    38  	require.Len(t, h, len(expected))
    39  	for _, nt := range expected {
    40  		typ, found := h[nt.name]
    41  		require.True(t, found, nt)
    42  		require.EqualValues(t, *nt.typ, *typ)
    43  	}
    44  }
    45  
    46  var schemaVal = `
    47  age:int .
    48  
    49  name: string .
    50   address: string .
    51  <http://scalar.com/helloworld/> : string .
    52  `
    53  
    54  func TestSchema(t *testing.T) {
    55  	require.NoError(t, ParseBytes([]byte(schemaVal), 1))
    56  	checkSchema(t, State().predicate, []nameType{
    57  		{"name", &pb.SchemaUpdate{
    58  			Predicate: "name",
    59  			ValueType: pb.Posting_STRING,
    60  		}},
    61  		{"address", &pb.SchemaUpdate{
    62  			Predicate: "address",
    63  			ValueType: pb.Posting_STRING,
    64  		}},
    65  		{"http://scalar.com/helloworld/", &pb.SchemaUpdate{
    66  			Predicate: "http://scalar.com/helloworld/",
    67  			ValueType: pb.Posting_STRING,
    68  		}},
    69  		{"age", &pb.SchemaUpdate{
    70  			Predicate: "age",
    71  			ValueType: pb.Posting_INT,
    72  		}},
    73  	})
    74  
    75  	typ, err := State().TypeOf("age")
    76  	require.NoError(t, err)
    77  	require.Equal(t, types.IntID, typ)
    78  
    79  	_, err = State().TypeOf("agea")
    80  	require.Error(t, err)
    81  }
    82  
    83  var schemaVal1 = `
    84  age:int .
    85  
    86  name: string .
    87  address: string .
    88  
    89  )
    90  `
    91  
    92  func TestSchema1_Error(t *testing.T) {
    93  	require.Error(t, ParseBytes([]byte(schemaVal1), 1))
    94  }
    95  
    96  var schemaVal2 = `
    97  name: ( string
    98  `
    99  
   100  func TestSchema2_Error(t *testing.T) {
   101  	require.Error(t, ParseBytes([]byte(schemaVal2), 1))
   102  }
   103  
   104  var schemaVal3 = `
   105  test test: int
   106  `
   107  
   108  func TestSchema3_Error(t *testing.T) {
   109  	require.Error(t, ParseBytes([]byte(schemaVal3), 1))
   110  }
   111  
   112  var schemaIndexVal1 = `
   113  age:int @index(int) .
   114  
   115  name: string .
   116  address: string @index(term) .`
   117  
   118  func TestSchemaIndex(t *testing.T) {
   119  	require.NoError(t, ParseBytes([]byte(schemaIndexVal1), 1))
   120  	require.Equal(t, 2, len(State().IndexedFields()))
   121  }
   122  
   123  var schemaIndexVal2 = `
   124  name: string @index(exact, exact) .
   125  address: string @index(term) .
   126  id: id @index(exact, term, exact) .
   127  `
   128  
   129  // Duplicate tokenizers
   130  func TestSchemaIndex_Error1(t *testing.T) {
   131  	require.Error(t, ParseBytes([]byte(schemaIndexVal2), 1))
   132  }
   133  
   134  var schemaIndexVal3Uid = `
   135  person: uid @index .
   136  `
   137  
   138  var schemaIndexVal3Default = `
   139  value: default @index .
   140  `
   141  
   142  var schemaIndexVal3Password = `
   143  pass: password @index .
   144  `
   145  
   146  // Object types cant be indexed.
   147  func TestSchemaIndex_Error2(t *testing.T) {
   148  	require.Error(t, ParseBytes([]byte(schemaIndexVal3Uid), 1))
   149  	require.Error(t, ParseBytes([]byte(schemaIndexVal3Default), 1))
   150  	require.Error(t, ParseBytes([]byte(schemaIndexVal3Password), 1))
   151  }
   152  
   153  var schemaIndexVal4 = `
   154  name:string @index(exact term) .
   155  `
   156  
   157  // Missing comma.
   158  func TestSchemaIndex_Error3(t *testing.T) {
   159  	require.Error(t, ParseBytes([]byte(schemaIndexVal4), 1))
   160  }
   161  
   162  var schemaIndexVal5 = `
   163  age     : int @index(int) .
   164  name    : string @index(exact) @count .
   165  address : string @index(term) .
   166  friend  : [uid] @reverse @count .
   167  `
   168  
   169  func TestSchemaIndexCustom(t *testing.T) {
   170  	require.NoError(t, ParseBytes([]byte(schemaIndexVal5), 1))
   171  	checkSchema(t, State().predicate, []nameType{
   172  		{"name", &pb.SchemaUpdate{
   173  			Predicate: "name",
   174  			ValueType: pb.Posting_STRING,
   175  			Tokenizer: []string{"exact"},
   176  			Directive: pb.SchemaUpdate_INDEX,
   177  			Count:     true,
   178  		}},
   179  		{"address", &pb.SchemaUpdate{
   180  			Predicate: "address",
   181  			ValueType: pb.Posting_STRING,
   182  			Tokenizer: []string{"term"},
   183  			Directive: pb.SchemaUpdate_INDEX,
   184  		}},
   185  		{"age", &pb.SchemaUpdate{
   186  			Predicate: "age",
   187  			ValueType: pb.Posting_INT,
   188  			Tokenizer: []string{"int"},
   189  			Directive: pb.SchemaUpdate_INDEX,
   190  		}},
   191  		{"friend", &pb.SchemaUpdate{
   192  			ValueType: pb.Posting_UID,
   193  			Predicate: "friend",
   194  			Directive: pb.SchemaUpdate_REVERSE,
   195  			Count:     true,
   196  			List:      true,
   197  		}},
   198  	})
   199  	require.True(t, State().IsIndexed("name"))
   200  	require.False(t, State().IsReversed("name"))
   201  	require.Equal(t, "int", State().Tokenizer("age")[0].Name())
   202  	require.Equal(t, 3, len(State().IndexedFields()))
   203  }
   204  
   205  func TestParse(t *testing.T) {
   206  	reset()
   207  	_, err := Parse("age:int @index . name:string")
   208  	require.Error(t, err)
   209  }
   210  
   211  func TestParse2(t *testing.T) {
   212  	reset()
   213  	result, err := Parse("")
   214  	require.NoError(t, err)
   215  	require.Nil(t, result.Preds)
   216  }
   217  
   218  func TestParse3_Error(t *testing.T) {
   219  	reset()
   220  	result, err := Parse("age:uid @index .")
   221  	require.Error(t, err)
   222  	require.Nil(t, result)
   223  }
   224  
   225  func TestParse4_Error(t *testing.T) {
   226  	reset()
   227  	result, err := Parse("alive:bool @index(geo) .")
   228  	require.Contains(t, err.Error(),
   229  		"Tokenizer: geo isn't valid for predicate: alive of type: bool")
   230  	require.Nil(t, result)
   231  }
   232  
   233  func TestParse4_NoError(t *testing.T) {
   234  	reset()
   235  	result, err := Parse("name:string @index(fulltext) .")
   236  	require.NotNil(t, result)
   237  	require.Nil(t, err)
   238  }
   239  
   240  func TestParse5_Error(t *testing.T) {
   241  	reset()
   242  	result, err := Parse("value:default @index .")
   243  	require.Error(t, err)
   244  	require.Nil(t, result)
   245  }
   246  
   247  func TestParse6_Error(t *testing.T) {
   248  	reset()
   249  	result, err := Parse("pass:password @index .")
   250  	require.Error(t, err)
   251  	require.Nil(t, result)
   252  }
   253  
   254  func TestParse7_Error(t *testing.T) {
   255  	reset()
   256  	result, err := Parse("name:string @index .")
   257  	require.Error(t, err)
   258  	require.Nil(t, result)
   259  }
   260  
   261  func TestParse8_Error(t *testing.T) {
   262  	reset()
   263  	result, err := Parse("dob:dateTime @index .")
   264  	require.Error(t, err)
   265  	require.Nil(t, result)
   266  }
   267  
   268  func TestParseScalarList(t *testing.T) {
   269  	reset()
   270  	result, err := Parse(`
   271  		jobs: [string] @index(term) .
   272  		occupations: [string] .
   273  		graduation: [dateTime] .
   274  	`)
   275  	require.NoError(t, err)
   276  	require.Equal(t, 3, len(result.Preds))
   277  	require.EqualValues(t, &pb.SchemaUpdate{
   278  		Predicate: "jobs",
   279  		ValueType: 9,
   280  		Directive: pb.SchemaUpdate_INDEX,
   281  		Tokenizer: []string{"term"},
   282  		List:      true,
   283  	}, result.Preds[0])
   284  
   285  	require.EqualValues(t, &pb.SchemaUpdate{
   286  		Predicate: "occupations",
   287  		ValueType: 9,
   288  		List:      true,
   289  	}, result.Preds[1])
   290  
   291  	require.EqualValues(t, &pb.SchemaUpdate{
   292  		Predicate: "graduation",
   293  		ValueType: 5,
   294  		List:      true,
   295  	}, result.Preds[2])
   296  }
   297  
   298  func TestParseScalarListError1(t *testing.T) {
   299  	reset()
   300  	result, err := Parse(`
   301  		friend: [string .
   302  	`)
   303  	require.Error(t, err)
   304  	require.Contains(t, err.Error(), "Unclosed [ while parsing schema for: friend")
   305  	require.Nil(t, result)
   306  }
   307  
   308  func TestParseScalarListError2(t *testing.T) {
   309  	reset()
   310  	result, err := Parse(`
   311  		friend: string] .
   312  	`)
   313  	require.Error(t, err)
   314  	require.Contains(t, err.Error(), "Invalid ending")
   315  	require.Nil(t, result)
   316  }
   317  
   318  func TestParseScalarListError3(t *testing.T) {
   319  	reset()
   320  	_, err := Parse(`
   321  		friend: [bool] .
   322  	`)
   323  	require.Error(t, err)
   324  	require.Contains(t, err.Error(), "Unsupported type for list: [bool]")
   325  }
   326  
   327  func TestParseUidList(t *testing.T) {
   328  	reset()
   329  	result, err := Parse(`
   330  		friend: [uid] .
   331  	`)
   332  	require.NoError(t, err)
   333  	require.Equal(t, 1, len(result.Preds))
   334  	require.EqualValues(t, &pb.SchemaUpdate{
   335  		Predicate: "friend",
   336  		ValueType: 7,
   337  		List:      true,
   338  	}, result.Preds[0])
   339  }
   340  
   341  func TestParseUidSingleValue(t *testing.T) {
   342  	reset()
   343  	result, err := Parse(`
   344  		friend: uid .
   345  	`)
   346  	require.NoError(t, err)
   347  	require.Equal(t, 1, len(result.Preds))
   348  	require.EqualValues(t, &pb.SchemaUpdate{
   349  		Predicate: "friend",
   350  		ValueType: 7,
   351  		List:      false,
   352  	}, result.Preds[0])
   353  }
   354  func TestParseUnderscore(t *testing.T) {
   355  	reset()
   356  	_, err := Parse("_share_:string @index(term) .")
   357  	require.NoError(t, err)
   358  }
   359  
   360  func TestParseUpsert(t *testing.T) {
   361  	reset()
   362  	_, err := Parse(`
   363  		jobs : string @index(exact) @upsert .
   364  		age  : int @index(int) @upsert .
   365  	`)
   366  	require.NoError(t, err)
   367  }
   368  
   369  func TestParseEmptyType(t *testing.T) {
   370  	reset()
   371  	result, err := Parse(`
   372  		type Person {
   373  
   374  		}
   375  	`)
   376  	require.NoError(t, err)
   377  	require.Equal(t, 1, len(result.Types))
   378  	require.Equal(t, &pb.TypeUpdate{
   379  		TypeName: "Person",
   380  	}, result.Types[0])
   381  
   382  }
   383  
   384  func TestParseSingleType(t *testing.T) {
   385  	reset()
   386  	result, err := Parse(`
   387  		type Person {
   388  			Name: string
   389  		}
   390  	`)
   391  	require.NoError(t, err)
   392  	require.Equal(t, 1, len(result.Types))
   393  	require.Equal(t, &pb.TypeUpdate{
   394  		TypeName: "Person",
   395  		Fields: []*pb.SchemaUpdate{
   396  			{
   397  				Predicate: "Name",
   398  				ValueType: pb.Posting_STRING,
   399  			},
   400  		},
   401  	}, result.Types[0])
   402  }
   403  
   404  func TestParseBaseTypesCaseInsensitive(t *testing.T) {
   405  	reset()
   406  	result, err := Parse(`
   407  		type Person {
   408  			Name: string
   409  			LastName: String
   410  		}
   411  	`)
   412  	require.NoError(t, err)
   413  	require.Equal(t, 1, len(result.Types))
   414  	require.Equal(t, &pb.TypeUpdate{
   415  		TypeName: "Person",
   416  		Fields: []*pb.SchemaUpdate{
   417  			{
   418  				Predicate: "Name",
   419  				ValueType: pb.Posting_STRING,
   420  			},
   421  			{
   422  				Predicate: "LastName",
   423  				ValueType: pb.Posting_STRING,
   424  			},
   425  		},
   426  	}, result.Types[0])
   427  }
   428  
   429  func TestParseCombinedSchemasAndTypes(t *testing.T) {
   430  	reset()
   431  	result, err := Parse(`
   432  		type Person {
   433  
   434  		}
   435          name: string .
   436  	`)
   437  	require.NoError(t, err)
   438  	require.Equal(t, 1, len(result.Preds))
   439  	require.Equal(t, &pb.SchemaUpdate{
   440  		Predicate: "name",
   441  		ValueType: 9,
   442  	}, result.Preds[0])
   443  	require.Equal(t, 1, len(result.Types))
   444  	require.Equal(t, &pb.TypeUpdate{
   445  		TypeName: "Person",
   446  	}, result.Types[0])
   447  }
   448  
   449  func TestParseMultipleTypes(t *testing.T) {
   450  	reset()
   451  	result, err := Parse(`
   452  		type Person {
   453  			Name: string
   454  		}
   455  		type Animal {
   456  			Name: string
   457  		}
   458  	`)
   459  	require.NoError(t, err)
   460  	require.Equal(t, 2, len(result.Types))
   461  	require.Equal(t, &pb.TypeUpdate{
   462  		TypeName: "Person",
   463  		Fields: []*pb.SchemaUpdate{
   464  			{
   465  				Predicate: "Name",
   466  				ValueType: pb.Posting_STRING,
   467  			},
   468  		},
   469  	}, result.Types[0])
   470  	require.Equal(t, &pb.TypeUpdate{
   471  		TypeName: "Animal",
   472  		Fields: []*pb.SchemaUpdate{
   473  			{
   474  				Predicate: "Name",
   475  				ValueType: pb.Posting_STRING,
   476  			},
   477  		},
   478  	}, result.Types[1])
   479  }
   480  
   481  func TestParseObjectType(t *testing.T) {
   482  	reset()
   483  	result, err := Parse(`
   484  		type Person {
   485  			Father: Person
   486  			Mother: Person
   487  			Children: [Person]
   488  		}
   489  	`)
   490  	require.NoError(t, err)
   491  	require.Equal(t, 1, len(result.Types))
   492  	require.Equal(t, &pb.TypeUpdate{
   493  		TypeName: "Person",
   494  		Fields: []*pb.SchemaUpdate{
   495  			{
   496  				Predicate:      "Father",
   497  				ValueType:      pb.Posting_OBJECT,
   498  				ObjectTypeName: "Person",
   499  			},
   500  			{
   501  				Predicate:      "Mother",
   502  				ValueType:      pb.Posting_OBJECT,
   503  				ObjectTypeName: "Person",
   504  			},
   505  			{
   506  				Predicate:      "Children",
   507  				ValueType:      pb.Posting_OBJECT,
   508  				ObjectTypeName: "Person",
   509  				List:           true,
   510  			},
   511  		},
   512  	}, result.Types[0])
   513  }
   514  
   515  func TestParseScalarType(t *testing.T) {
   516  	reset()
   517  	result, err := Parse(`
   518  		type Person {
   519  			Name: string
   520  			Nickname: [String]
   521  			Alive: Bool
   522  		}
   523  	`)
   524  	require.NoError(t, err)
   525  	require.Equal(t, 1, len(result.Types))
   526  	require.Equal(t, &pb.TypeUpdate{
   527  		TypeName: "Person",
   528  		Fields: []*pb.SchemaUpdate{
   529  			{
   530  				Predicate: "Name",
   531  				ValueType: pb.Posting_STRING,
   532  			},
   533  			{
   534  				Predicate: "Nickname",
   535  				ValueType: pb.Posting_STRING,
   536  				List:      true,
   537  			},
   538  			{
   539  				Predicate: "Alive",
   540  				ValueType: pb.Posting_BOOL,
   541  			},
   542  		},
   543  	}, result.Types[0])
   544  }
   545  
   546  func TestParseCombinedTypes(t *testing.T) {
   547  	reset()
   548  	result, err := Parse(`
   549  		type Person {
   550  			Name: string
   551  			Nickname: [string]
   552  			Parents: [Person]
   553  		}
   554  	`)
   555  	require.NoError(t, err)
   556  	require.Equal(t, 1, len(result.Types))
   557  	require.Equal(t, &pb.TypeUpdate{
   558  		TypeName: "Person",
   559  		Fields: []*pb.SchemaUpdate{
   560  			{
   561  				Predicate: "Name",
   562  				ValueType: pb.Posting_STRING,
   563  			},
   564  			{
   565  				Predicate: "Nickname",
   566  				ValueType: pb.Posting_STRING,
   567  				List:      true,
   568  			},
   569  			{
   570  				Predicate:      "Parents",
   571  				ValueType:      pb.Posting_OBJECT,
   572  				ObjectTypeName: "Person",
   573  				List:           true,
   574  			},
   575  		},
   576  	}, result.Types[0])
   577  }
   578  
   579  func TestParseNonNullableScalar(t *testing.T) {
   580  	reset()
   581  	result, err := Parse(`
   582  		type Person {
   583  			Name: string!
   584  			Nickname: [string]
   585  		}
   586  	`)
   587  	require.NoError(t, err)
   588  	require.Equal(t, 1, len(result.Types))
   589  	require.Equal(t, &pb.TypeUpdate{
   590  		TypeName: "Person",
   591  		Fields: []*pb.SchemaUpdate{
   592  			{
   593  				Predicate:   "Name",
   594  				ValueType:   pb.Posting_STRING,
   595  				NonNullable: true,
   596  			},
   597  			{
   598  				Predicate: "Nickname",
   599  				ValueType: pb.Posting_STRING,
   600  				List:      true,
   601  			},
   602  		},
   603  	}, result.Types[0])
   604  }
   605  
   606  func TestParseNonNullableList(t *testing.T) {
   607  	reset()
   608  	result, err := Parse(`
   609  		type Person {
   610  			Name: string
   611  			Nickname: [string]!
   612  		}
   613  	`)
   614  	require.NoError(t, err)
   615  	require.Equal(t, 1, len(result.Types))
   616  	require.Equal(t, &pb.TypeUpdate{
   617  		TypeName: "Person",
   618  		Fields: []*pb.SchemaUpdate{
   619  			{
   620  				Predicate: "Name",
   621  				ValueType: pb.Posting_STRING,
   622  			},
   623  			{
   624  				Predicate:       "Nickname",
   625  				ValueType:       pb.Posting_STRING,
   626  				List:            true,
   627  				NonNullableList: true,
   628  			},
   629  		},
   630  	}, result.Types[0])
   631  }
   632  
   633  func TestParseNonNullableScalarAndList(t *testing.T) {
   634  	reset()
   635  	result, err := Parse(`
   636  		type Person {
   637  			Name: string!
   638  			Nickname: [string!]!
   639  		}
   640  	`)
   641  	require.NoError(t, err)
   642  	require.Equal(t, 1, len(result.Types))
   643  	require.Equal(t, &pb.TypeUpdate{
   644  		TypeName: "Person",
   645  		Fields: []*pb.SchemaUpdate{
   646  			{
   647  				Predicate:   "Name",
   648  				ValueType:   pb.Posting_STRING,
   649  				NonNullable: true,
   650  			},
   651  			{
   652  				Predicate:       "Nickname",
   653  				ValueType:       pb.Posting_STRING,
   654  				List:            true,
   655  				NonNullable:     true,
   656  				NonNullableList: true,
   657  			},
   658  		},
   659  	}, result.Types[0])
   660  }
   661  
   662  func TestParseTypeErrMissingNewLine(t *testing.T) {
   663  	reset()
   664  	_, err := Parse(`
   665  		type Person {
   666  		}type Animal {}
   667  	`)
   668  	require.Error(t, err)
   669  	require.Contains(t, err.Error(), "Expected new line after type declaration")
   670  }
   671  
   672  func TestParseTypeErrMissingColon(t *testing.T) {
   673  	reset()
   674  	_, err := Parse(`
   675  		type Person {
   676  			Name string
   677  		}
   678  	`)
   679  	require.Error(t, err)
   680  	require.Contains(t, err.Error(), "Missing colon in type declaration")
   681  }
   682  
   683  func TestParseTypeErrMultipleTypes(t *testing.T) {
   684  	reset()
   685  	_, err := Parse(`
   686  		type Person {
   687  			Name: bool string
   688  		}
   689  	`)
   690  	require.Error(t, err)
   691  	require.Contains(t, err.Error(), "Expected new line after field declaration")
   692  }
   693  
   694  func TestParseTypeErrMultipleExclamationMarks(t *testing.T) {
   695  	reset()
   696  	_, err := Parse(`
   697  		type Person {
   698  			Name: bool!!
   699  		}
   700  	`)
   701  	require.Error(t, err)
   702  	require.Contains(t, err.Error(), "Expected new line after field declaration")
   703  }
   704  
   705  func TestParseTypeErrMissingSquareBracket(t *testing.T) {
   706  	reset()
   707  	_, err := Parse(`
   708  		type Person {
   709  			Name: [string
   710  		}
   711  	`)
   712  	require.Error(t, err)
   713  	require.Contains(t, err.Error(), "Expected matching square bracket")
   714  }
   715  
   716  func TestParseTypeErrMultipleSquareBrackets(t *testing.T) {
   717  	reset()
   718  	_, err := Parse(`
   719  		type Person {
   720  			Name: [[string]]
   721  		}
   722  	`)
   723  	require.Error(t, err)
   724  	require.Contains(t, err.Error(), "Missing field type in type declaration")
   725  }
   726  
   727  func TestParseTypeErrMissingType(t *testing.T) {
   728  	reset()
   729  	_, err := Parse(`
   730  		type Person {
   731  			Name:
   732  		}
   733  	`)
   734  	require.Error(t, err)
   735  	require.Contains(t, err.Error(), "Missing field type in type declaration")
   736  }
   737  
   738  func TestParseComments(t *testing.T) {
   739  	reset()
   740  	_, err := Parse(`
   741  		#
   742  		# This is a test
   743  		#
   744  		user: bool .
   745  		user.name: string @index(exact) . # this should be unique
   746  		user.email: string @index(exact) . # this should be unique and lower-cased
   747  		user.password: password .
   748  		user.code: string . # for password recovery (can be null)
   749  		node: bool .
   750  		node.hashid: string @index(exact) . # @username/hashid
   751  		node.owner: uid @reverse . # (can be null)
   752  		node.parent: uid . # [uid] (use facet)
   753  		node.xdata: string . # store custom json data
   754  		#
   755  		# End of test
   756  		#
   757  	`)
   758  	require.NoError(t, err)
   759  }
   760  
   761  func TestParseCommentsNoop(t *testing.T) {
   762  	reset()
   763  	_, err := Parse(`
   764  # Spicy jalapeno bacon ipsum dolor amet t-bone kevin spare ribs sausage jowl cow pastrami short.
   765  # Leberkas alcatra kielbasa chicken pastrami swine bresaola. Spare ribs landjaeger meatloaf.
   766  # Chicken biltong boudin porchetta jowl swine burgdoggen cow kevin ground round landjaeger ham.
   767  # Tongue buffalo cow filet mignon boudin sirloin pancetta pork belly beef ribs. Cow landjaeger.
   768  	`)
   769  	require.NoError(t, err)
   770  }
   771  
   772  func TestParseCommentsErrMissingType(t *testing.T) {
   773  	reset()
   774  	_, err := Parse(`
   775  		# The definition below should trigger an error
   776  		# because we commented out its type.
   777  		node: # bool .
   778  	`)
   779  	require.Error(t, err)
   780  	require.Contains(t, err.Error(), "Missing Type")
   781  }
   782  
   783  func TestParseTypeComments(t *testing.T) {
   784  	reset()
   785  	_, err := Parse(`
   786  		# User is a service user
   787  		type User {
   788  			# TODO: add more fields
   789  			Name: string # e.g., srfrog
   790  									 # expanded comment
   791  									 # embedded # comments # here
   792  		}
   793  		# /User
   794  	`)
   795  	require.NoError(t, err)
   796  }
   797  
   798  var ps *badger.DB
   799  
   800  func TestMain(m *testing.M) {
   801  	x.Init()
   802  
   803  	dir, err := ioutil.TempDir("", "storetest_")
   804  	x.Check(err)
   805  	kvOpt := badger.DefaultOptions(dir)
   806  	ps, err = badger.OpenManaged(kvOpt)
   807  	x.Check(err)
   808  	Init(ps)
   809  
   810  	r := m.Run()
   811  
   812  	ps.Close()
   813  	os.RemoveAll(dir)
   814  	os.Exit(r)
   815  }