1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 /**
28 * Unit tests for schema parser
29 */
30 
31 #include <ktst/unit_test.hpp>
32 
33 #include <sstream>
34 #include <fstream>
35 #include <cstring>
36 
37 #include <kfs/directory.h>
38 #include <kfs/file.h>
39 
40 #include "../../libs/schema/SchemaParser.hpp"
41 #include "../../libs/schema/ParseTree.hpp"
42 
43 using namespace ncbi::SchemaParser;
44 #include "../../libs/schema/schema-tokens.h"
45 
46 using namespace std;
47 using namespace ncbi::NK;
48 
49 const string DataDir = "./actual";
50 
51 TEST_SUITE ( SchemaParserTestSuite );
52 
53 #define KW_TOKEN(v,k) Token v ( KW_##k, #k)
54 
55 KW_TOKEN( st  ,virtual );
56 KW_TOKEN( st0 ,void );
57 KW_TOKEN( st1 ,write );
58 KW_TOKEN( st2 ,version );
59 KW_TOKEN( st3 ,include );
60 
61 // Token
TEST_CASE(Token_Construct)62 TEST_CASE(Token_Construct)
63 {
64     REQUIRE_EQ ( ( int ) KW_virtual, st . GetType() );
65     REQUIRE_EQ ( string ( "virtual" ), string ( st . GetValue() ) );
66     REQUIRE ( ! st . IsFake () );
67 }
68 
TEST_CASE(Token_Construct_WithLocation)69 TEST_CASE(Token_Construct_WithLocation)
70 {
71     Token :: Location loc ("qq", 1, 2 );
72     Token t ( KW_virtual, "virtual", loc );
73     REQUIRE_EQ ( string ( loc . m_file ), string ( t . GetLocation () . m_file ) );
74     REQUIRE_EQ ( loc . m_line, t . GetLocation () . m_line );
75     REQUIRE_EQ ( loc . m_column, t . GetLocation () . m_column );
76 }
77 
TEST_CASE(Token_Construct_Fake)78 TEST_CASE(Token_Construct_Fake)
79 {
80     Token t ( 42 );
81     REQUIRE ( t . IsFake () );
82 }
83 
84 // ParseTree
85 bool
operator ==(const Token & l,const Token & r)86 operator == ( const Token & l, const Token & r)
87 {
88     return l . GetType() == r . GetType() && string ( l . GetValue() ) == string ( r . GetValue() );
89 }
90 
TEST_CASE(ParseTree_Construct)91 TEST_CASE(ParseTree_Construct)
92 {
93     ParseTree t ( st );
94     REQUIRE ( t . GetToken() == Token ( st ) );
95 }
96 
TEST_CASE(ParseTree_AddChild)97 TEST_CASE(ParseTree_AddChild)
98 {
99     ParseTree t = Token ( PT_PARSE );
100     t. AddChild ( new ParseTree ( st0 ) );
101     t. AddChild ( new ParseTree ( st1 ) );
102 
103     REQUIRE ( t . GetChild ( 0 ) -> GetToken () == Token ( st0 ) );
104     REQUIRE ( t . GetChild ( 1 ) -> GetToken () == Token ( st1 ) );
105 }
TEST_CASE(ParseTree_ChildrenCount)106 TEST_CASE(ParseTree_ChildrenCount)
107 {
108     ParseTree t = Token ( PT_PARSE );
109     t. AddChild ( new ParseTree ( st0 ) );
110     t. AddChild ( new ParseTree ( st1 ) );
111 
112     REQUIRE_EQ ( 2u, t . ChildrenCount () );
113 }
114 
TEST_CASE(ParseTree_MoveChildren)115 TEST_CASE(ParseTree_MoveChildren)
116 {
117     ParseTree source = Token ( PT_PARSE );
118     source. AddChild ( new ParseTree ( st0 ) );
119     source. AddChild ( new ParseTree ( st1 ) );
120 
121     class TestTree : public ParseTree
122     {
123     public:
124         using ParseTree :: MoveChildren;
125         TestTree(const Token & p_t) : ParseTree( p_t ) {};
126     } target ( st );
127 
128     target . MoveChildren ( source );
129 
130     REQUIRE_EQ ( 0u, source . ChildrenCount () );
131 
132     REQUIRE_EQ ( 2u, target . ChildrenCount () );
133     REQUIRE ( target . GetChild ( 0 ) -> GetToken () == Token ( st0 ) );
134     REQUIRE ( target . GetChild ( 1 ) -> GetToken () == Token ( st1 ) );
135 }
136 
TEST_CASE(ParseTree_Location)137 TEST_CASE(ParseTree_Location)
138 {
139     // start with a fake token, its empty location is used as the tree's location
140     ParseTree source = Token ( PT_PARSE );
141     REQUIRE_EQ ( string (), string ( source . GetLocation() . m_file ) );
142     REQUIRE_EQ ( 0u, source . GetLocation() . m_line );
143     REQUIRE_EQ ( 0u, source . GetLocation() . m_column );
144 
145     // add a real token, make sure its location is used as the tree's location
146     SchemaToken st1 = { KW_view, "view", 4, 0, 0, "file", 1, 2 };
147     source . AddChild ( new ParseTree ( st1 ) );
148     REQUIRE_EQ ( string ( "file" ), string ( source . GetLocation() . m_file ) ); // first real token
149     REQUIRE_EQ ( 1u, source . GetLocation() . m_line );
150     REQUIRE_EQ ( 2u, source . GetLocation() . m_column );
151 
152     // add more real tokens, make sure the location does not change
153     SchemaToken st2 = { KW_view, "view", 4, 0, 0, "file", 2, 3 };
154     source . AddChild ( new ParseTree ( st2 ) );
155     REQUIRE_EQ ( 1u, source . GetLocation() . m_line );
156     REQUIRE_EQ ( 2u, source . GetLocation() . m_column );
157 }
158 
159 // SchemaParser
160 
TEST_CASE(SchemaParser_ParseString)161 TEST_CASE(SchemaParser_ParseString)
162 {
163     SchemaParser p;
164     REQUIRE ( p . ParseString ( "" ) );
165     REQUIRE_NOT_NULL ( p . GetParseTree () );
166 }
167 
TEST_CASE(SchemaParser_ParseFile)168 TEST_CASE(SchemaParser_ParseFile)
169 {
170     const string FileName = DataDir + "/" + GetName ();
171     {
172         ofstream out ( FileName . c_str () );
173         out << " ";
174     }
175 
176     const KFile * f;
177     KDirectory *wd;
178     REQUIRE_RC ( KDirectoryNativeDir ( & wd ) );
179     REQUIRE_RC ( KDirectoryOpenFileRead ( wd, & f, "%s", FileName . c_str () ) );
180     KDirectoryRelease ( wd );
181 
182     SchemaParser p;
183     REQUIRE ( p . ParseFile ( f ) );
184     REQUIRE_NOT_NULL ( p . GetParseTree () );
185     KFileRelease ( f );
186 }
187 
TEST_CASE(SchemaParser_MoveParseTree)188 TEST_CASE(SchemaParser_MoveParseTree)
189 {
190     SchemaParser p;
191     p . ParseString ( "" );
192     ParseTree * root = p . MoveParseTree ();
193     REQUIRE_NULL ( p . GetParseTree () );
194     delete root;
195 }
196 
197 // Grammar
198 
199 static
200 void
PrintParseTree(const ParseTree * p_t,ostream & p_out)201 PrintParseTree ( const ParseTree * p_t, ostream& p_out )
202 {
203     if ( p_t == 0 )
204     {
205         p_out << " NULL";
206         return;
207     }
208 
209     p_out << p_t -> GetToken () . GetLeadingWhitespace () << p_t -> GetToken () . GetValue ();
210 
211     for ( uint32_t i = 0 ; i < p_t -> ChildrenCount (); ++ i )
212     {
213         PrintParseTree ( p_t -> GetChild ( i ), p_out );
214     }
215 }
216 
217 static
218 void
ParseAndVerify(const char * p_source,bool p_debug=false)219 ParseAndVerify ( const char* p_source, bool p_debug = false )
220 {
221     SchemaParser p;
222     if ( ! p . ParseString ( p_source, p_debug ) )
223     {
224         throw logic_error ( string ( "ParseAndVerify : ParseString() failed: " ) + p . GetErrors () . GetMessageText ( 0 ) );
225     }
226     ostringstream str;
227     PrintParseTree ( p . GetParseTree (), str );
228     if ( str . str () != p_source )
229     {
230         cout << "expected: '" << p_source << "'" << endl
231              << "actual:   '" << str . str () << "'" << endl;
232         throw logic_error ( "ParseAndVerify failed: " );
233     }
234 }
235 
TEST_CASE(EmptyInput)236 TEST_CASE ( EmptyInput )
237 {
238     ParseAndVerify ( "" );
239 }
240 
TEST_CASE(Version1)241 TEST_CASE ( Version1 )
242 {
243     ParseAndVerify ( "version 1; include \"qq\";" );
244 }
245 
TEST_CASE(MultipleDecls)246 TEST_CASE ( MultipleDecls )
247 {
248     ParseAndVerify ( "version 1; include \"qq\"; include \"aa\";" );
249 }
250 
TEST_CASE(Typedef)251 TEST_CASE ( Typedef )
252 {
253     ParseAndVerify ( "typedef ns:oldName newName;" );
254 }
TEST_CASE(Keywords_as_identifiers)255 TEST_CASE ( Keywords_as_identifiers )
256 {
257     ParseAndVerify (
258         "typedef ns:database:decode:encode:read:table:type:view:write newName;" );
259 }
260 
TEST_CASE(TypedefDim)261 TEST_CASE ( TypedefDim )
262 {
263     ParseAndVerify ( "typedef oldName newName [ 12 ];" );
264 }
TEST_CASE(TypedefVarDim)265 TEST_CASE ( TypedefVarDim )
266 {
267     ParseAndVerify ( "typedef oldName newName [ * ];" );
268 }
269 
TEST_CASE(TypedefMultipleNames)270 TEST_CASE ( TypedefMultipleNames )
271 {
272     ParseAndVerify ( "typedef oldName neawName1, newName2 [ 12 ], newName3;" );
273 }
274 
TEST_CASE(Typeset)275 TEST_CASE ( Typeset )
276 {
277     ParseAndVerify ( "typeset newName { a, b[1], c };" );
278 }
279 
TEST_CASE(Format)280 TEST_CASE ( Format )
281 {
282     ParseAndVerify ( "fmtdef newName;" );
283 }
TEST_CASE(FormatRename)284 TEST_CASE ( FormatRename )
285 {
286     ParseAndVerify ( "fmtdef oldName newName;" );
287 }
288 
TEST_CASE(Const)289 TEST_CASE ( Const )
290 {
291     ParseAndVerify ( "const t c = 1;" );
292 }
TEST_CASE(ConstDim)293 TEST_CASE ( ConstDim )
294 {
295     ParseAndVerify ( "const t[2] c = 1;" );
296 }
297 
TEST_CASE(Alias)298 TEST_CASE ( Alias )
299 {
300     ParseAndVerify ( "alias a b;" );
301 }
302 
TEST_CASE(Extern_AndUntyped)303 TEST_CASE ( Extern_AndUntyped )
304 {
305     ParseAndVerify ( "extern function __untyped fn ();" );
306 }
307 
TEST_CASE(Function_RowLength)308 TEST_CASE ( Function_RowLength )
309 {
310     ParseAndVerify ( "function __row_length fn ();" );
311 }
312 
TEST_CASE(Function_Naked)313 TEST_CASE ( Function_Naked )
314 {
315     ParseAndVerify ( "function t fn ( a b );" );
316 }
317 
TEST_CASE(Function_ArrayReturn)318 TEST_CASE ( Function_ArrayReturn )
319 {
320     ParseAndVerify ( "function t[3] fn ( a b );" );
321 }
322 
TEST_CASE(Function_Schema)323 TEST_CASE ( Function_Schema )
324 {
325     ParseAndVerify ( "function < type b,  a / fmt c > t fn ( a b );" );
326 }
327 
TEST_CASE(Function_Factory)328 TEST_CASE ( Function_Factory )
329 {
330     ParseAndVerify ( "function t fn < a b, c d > ( a b );" );
331 }
332 
TEST_CASE(Function_NoFormals)333 TEST_CASE ( Function_NoFormals )
334 {
335     ParseAndVerify ( "function t fn ();" );
336 }
337 
TEST_CASE(Function_Formals_OptionalOnly)338 TEST_CASE ( Function_Formals_OptionalOnly )
339 {
340     ParseAndVerify ( "function t fn ( * a b );" );
341 }
TEST_CASE(Function_Formals_MandatoryAndOptional_NoComma)342 TEST_CASE ( Function_Formals_MandatoryAndOptional_NoComma )
343 {
344     ParseAndVerify ( "function t fn ( a b * a b );" );
345 }
TEST_CASE(Function_Formals_MandatoryAndOptional)346 TEST_CASE ( Function_Formals_MandatoryAndOptional )
347 {
348     ParseAndVerify ( "function t fn ( a b, * a b );" );
349 }
TEST_CASE(Function_Formals_MandatoryAndVariadic)350 TEST_CASE ( Function_Formals_MandatoryAndVariadic )
351 {
352     ParseAndVerify ( "function t fn ( a b, ...  );" );
353 }
TEST_CASE(Function_Formals_MandatoryOptionalAndVariadic)354 TEST_CASE ( Function_Formals_MandatoryOptionalAndVariadic )
355 {
356     ParseAndVerify ( "function t fn ( a b, * a b, ...  );" );
357 }
TEST_CASE(Function_Formals_Control)358 TEST_CASE ( Function_Formals_Control )
359 {
360     ParseAndVerify ( "function t fn ( control a b );" );
361 }
362 
TEST_CASE(Function_Prologue_Rename)363 TEST_CASE ( Function_Prologue_Rename )
364 {
365     ParseAndVerify ( "function t fn ( a b ) = fn;" );
366 }
TEST_CASE(Function_Prologue_Script_Return)367 TEST_CASE ( Function_Prologue_Script_Return )
368 {
369     ParseAndVerify ( "schema t fn ( a b ) { return 1; };" );
370 }
TEST_CASE(Function_Prologue_Script_Assign)371 TEST_CASE ( Function_Prologue_Script_Assign )
372 {
373     ParseAndVerify ( "schema function t fn ( a b ) { a c = 1; };" );
374 }
375 
TEST_CASE(Script)376 TEST_CASE ( Script )
377 {
378     ParseAndVerify ( "schema t fn ( a b );" );
379 }
TEST_CASE(Script_Function)380 TEST_CASE ( Script_Function )
381 {
382     ParseAndVerify ( "schema function t fn ( a b );" );
383 }
384 
TEST_CASE(Validate)385 TEST_CASE ( Validate )
386 {
387     ParseAndVerify ( "validate function t fn ( a b );" );
388 }
389 
TEST_CASE(Physical_Shorthand)390 TEST_CASE ( Physical_Shorthand )
391 {
392     ParseAndVerify ( "physical t fn #1.0 = { return 1; };" );
393 }
394 
TEST_CASE(Physical_Longhand)395 TEST_CASE ( Physical_Longhand )
396 {
397     ParseAndVerify (
398         "physical t fn #1.0 { decode { return 1; } ; encode { return 1; } ; __row_length = f () };" );
399 }
400 
TEST_CASE(Physical_noheader)401 TEST_CASE ( Physical_noheader )
402 {
403     ParseAndVerify (
404         "physical __no_header t fn #1.0 = { return a; };" );
405 }
406 
TEST_CASE(Table_NoParents)407 TEST_CASE ( Table_NoParents )
408 {
409     ParseAndVerify ( "table t #1.1.1 { t a = 1; };" );
410 }
TEST_CASE(Table_Parents)411 TEST_CASE ( Table_Parents )
412 {
413     ParseAndVerify ( "table t #1.1.1 = t1, t2, t3 { t a = 1; };" );
414 }
TEST_CASE(Table_ParentsWithVersion)415 TEST_CASE ( Table_ParentsWithVersion )
416 {
417     ParseAndVerify ( "table t #1.1.1 = t1, t2, t3#1.2.3 { t a = 1; };" );
418 }
419 
TEST_CASE(Table_Empty)420 TEST_CASE ( Table_Empty )
421 {
422     ParseAndVerify ( "table t #1 {};" );
423 }
TEST_CASE(Table_ProdStmt)424 TEST_CASE ( Table_ProdStmt )
425 {
426     ParseAndVerify ( "table t #1 { t a = 1; };" );
427 }
TEST_CASE(Table_ProdStmt_FunCallSchemaNoFormals)428 TEST_CASE ( Table_ProdStmt_FunCallSchemaNoFormals )
429 {
430     ParseAndVerify ( "table t #1 { t p = < t, 1 > fn < 1 > (); };" );
431 }
432 
TEST_CASE(Table_Column)433 TEST_CASE ( Table_Column )
434 {
435     ParseAndVerify ( "table t #1 { column t c; };" );
436 }
TEST_CASE(Table_Column_PhysicalEncoding)437 TEST_CASE ( Table_Column_PhysicalEncoding)
438 {
439     ParseAndVerify ( "table t #1 { column <1> p c; };" );
440 }
TEST_CASE(Table_Column_PhysicalEncoding_WithVersion)441 TEST_CASE ( Table_Column_PhysicalEncoding_WithVersion )
442 {
443     ParseAndVerify ( "table t #1 { column <1> p#1.2.3 c; };" );
444 }
TEST_CASE(Table_Column_PhysicalEncoding_WithFactory)445 TEST_CASE ( Table_Column_PhysicalEncoding_WithFactory )
446 {
447     ParseAndVerify ( "table t #1 { column <1> p <1> c; };" );
448 }
TEST_CASE(Table_Column_PhysicalEncoding_WithVersionAndFactory)449 TEST_CASE ( Table_Column_PhysicalEncoding_WithVersionAndFactory )
450 {
451     ParseAndVerify ( "table t #1 { column <1> p#1 <1> c; };" );
452 }
TEST_CASE(Table_Column_Default)453 TEST_CASE ( Table_Column_Default )
454 {
455     ParseAndVerify ( "table t #1 { default column t c; };" );
456 }
TEST_CASE(Table_Column_Extern_WithPhysical)457 TEST_CASE ( Table_Column_Extern_WithPhysical )
458 {
459     ParseAndVerify ( "table t #1 { extern column < U32 > izip_encoding #1 CHANNEL; };" );
460 }
TEST_CASE(Table_Column_Extern_WithNakedPhysical)461 TEST_CASE ( Table_Column_Extern_WithNakedPhysical )
462 {
463     ParseAndVerify ( "table t #1 { extern column bool_encoding #1 HIGH_QUALITY; };" );
464 }
TEST_CASE(Table_Column_Extern_WithPhysicalFactory)465 TEST_CASE ( Table_Column_Extern_WithPhysicalFactory )
466 {
467     ParseAndVerify ( "table t #1 {  column F32_4ch_encoding < 24 > BASE_FRACTION; };" );
468 }
469 
TEST_CASE(Table_Column_Readonly)470 TEST_CASE ( Table_Column_Readonly )
471 {
472     ParseAndVerify ( "table t #1 { readonly column t c; };" );
473 }
TEST_CASE(Table_Column_AllMods)474 TEST_CASE ( Table_Column_AllMods )
475 {
476     ParseAndVerify ( "table t #1 { default extern readonly column t c; };" );
477 }
478 
TEST_CASE(Table_Column_limit)479 TEST_CASE ( Table_Column_limit )
480 {
481     ParseAndVerify ( "table t #1 { column limit = 1; };" );
482 }
TEST_CASE(Table_Column_default_limit)483 TEST_CASE ( Table_Column_default_limit )
484 {
485     ParseAndVerify ( "table t #1 { column default limit = 1; };" );
486 }
487 
TEST_CASE(Table_Column_withBody_1)488 TEST_CASE ( Table_Column_withBody_1 )
489 {
490     ParseAndVerify ( "table t #1 { column t c { read = 1 | 2; validate = 2 | 3; limit = 100; }; };" );
491 }
TEST_CASE(Table_Column_withBody_2)492 TEST_CASE ( Table_Column_withBody_2 )
493 {
494     ParseAndVerify ( "table t #1 { column t c { read = 1 | 2; validate = 2 | 3; limit = 100; } };" );
495 }
TEST_CASE(Table_Column_withExpr)496 TEST_CASE ( Table_Column_withExpr )
497 {
498     ParseAndVerify ( "table t #1 { column t c = 0 | 1; };" );
499 }
500 
TEST_CASE(Table_DefaultView)501 TEST_CASE ( Table_DefaultView )
502 {
503     ParseAndVerify ( "table t #1 { default view \"QQ\"; };" );
504 }
505 
TEST_CASE(Table_PhysMbr_Static)506 TEST_CASE ( Table_PhysMbr_Static )
507 {
508     ParseAndVerify ( "table t #1 { static t .c; };" );
509 }
TEST_CASE(Table_PhysMbr_StaticWithInit)510 TEST_CASE ( Table_PhysMbr_StaticWithInit )
511 {
512     ParseAndVerify ( "table t #1 { static t .c = 1; };" );
513 }
TEST_CASE(Table_PhysMbr_Physical)514 TEST_CASE ( Table_PhysMbr_Physical )
515 {
516     ParseAndVerify ( "table t #1 { physical t .c = 1; };" );
517 }
TEST_CASE(Table_PhysMbr_PhysicalWithVersion)518 TEST_CASE ( Table_PhysMbr_PhysicalWithVersion )
519 {
520     ParseAndVerify ( "table t #1 { physical column NCBI #1 .CLIP_ADAPTER_LEFT; };" );
521 }
522 
TEST_CASE(Table_PhysMbr_StaticPhysical)523 TEST_CASE ( Table_PhysMbr_StaticPhysical )
524 {
525     ParseAndVerify ( "table t #1 { static physical t .c = 1; };" );
526 }
TEST_CASE(Table_PhysMbr_WithColumn)527 TEST_CASE ( Table_PhysMbr_WithColumn )
528 {
529     ParseAndVerify ( "table t #1 { static column t .c = 1; };" );
530 }
531 
TEST_CASE(Table_PhysMbr_WithSchema)532 TEST_CASE ( Table_PhysMbr_WithSchema )
533 {
534     ParseAndVerify ( "table t #1 { static column <1, 2> t .c = 1; };" );
535 }
TEST_CASE(Table_PhysMbr_WithVersion)536 TEST_CASE ( Table_PhysMbr_WithVersion )
537 {
538     ParseAndVerify ( "table t #1 { static column t#1 .c = 1; };" );
539 }
TEST_CASE(Table_PhysMbr_WithFactory)540 TEST_CASE ( Table_PhysMbr_WithFactory )
541 {
542     ParseAndVerify ( "table t #1 { static column t<1> .c = 1; };" );
543 }
TEST_CASE(Table_PhysMbr_WithAll)544 TEST_CASE ( Table_PhysMbr_WithAll )
545 {
546     ParseAndVerify ( "table t #1 { static column <1, t = a:b> t #2.3.4 < 5 > .c = 1; };" );
547 }
548 
TEST_CASE(Table_Untyped)549 TEST_CASE ( Table_Untyped )
550 {
551     ParseAndVerify ( "table t #1 { __untyped = a:b(); };" );
552 }
553 
TEST_CASE(Database_Empty)554 TEST_CASE ( Database_Empty )
555 {
556     ParseAndVerify ( "database a:b #1.2.3 {};" );
557 }
TEST_CASE(Database_WithParent)558 TEST_CASE ( Database_WithParent )
559 {
560     ParseAndVerify ( "database a:b #1.2.3 = ns:dad #4.5.6 {};" );
561 }
562 
TEST_CASE(Database_DbMember)563 TEST_CASE ( Database_DbMember )
564 {
565     ParseAndVerify ( "database d#1 { database ns : db DB; };" );
566 }
TEST_CASE(Database_DbMember_WithTemplate)567 TEST_CASE ( Database_DbMember_WithTemplate )
568 {
569     ParseAndVerify ( "database d#1 { template database ns : db DB; };" );
570 }
571 
TEST_CASE(Database_TableMember)572 TEST_CASE ( Database_TableMember )
573 {
574     ParseAndVerify ( "database d#1 { table ns : tbl T; };" );
575 }
TEST_CASE(Database_TableMember_WithTemplate)576 TEST_CASE ( Database_TableMember_WithTemplate )
577 {
578     ParseAndVerify ( "database d#1 { template table ns : tbl T; };" );
579 }
580 
TEST_CASE(Database_MultipleMembers)581 TEST_CASE ( Database_MultipleMembers )
582 {
583     ParseAndVerify ( "database d#1 { database ns : db DB; table ns : tbl T; };" );
584 }
585 
TEST_CASE(Include)586 TEST_CASE ( Include )
587 {
588     ParseAndVerify ( "include 'insdc/sra.vschema';" );
589 }
590 
591 // Expressions
TEST_CASE(CastExpr)592 TEST_CASE ( CastExpr )
593 {
594     ParseAndVerify ( "function t f() { return (a)b; };" );
595 }
596 
TEST_CASE(AtExpr)597 TEST_CASE ( AtExpr )
598 {
599     ParseAndVerify ( "function t f() { return @; };" );
600 }
601 
TEST_CASE(HexExpr)602 TEST_CASE ( HexExpr )
603 {
604     ParseAndVerify ( "function t f() { return 0x1290ABEF; };" );
605 }
606 
TEST_CASE(FloatExpr)607 TEST_CASE ( FloatExpr )
608 {
609     ParseAndVerify ( "function t f() { return 1.2; };" );
610 }
611 
TEST_CASE(ExpFloatExpr)612 TEST_CASE ( ExpFloatExpr )
613 {
614     ParseAndVerify ( "function t f() { return 1E2; };" );
615 }
616 
TEST_CASE(StringExpr)617 TEST_CASE ( StringExpr )
618 {
619     ParseAndVerify ( "function t f() { return \"qq\"; };" );
620 }
621 
TEST_CASE(EscapedStringExpr)622 TEST_CASE ( EscapedStringExpr )
623 {
624     ParseAndVerify ( "function t f() { return \"q\\q\"; };" );
625 }
626 
TEST_CASE(ConstVectExpr_Empty)627 TEST_CASE ( ConstVectExpr_Empty )
628 {
629     ParseAndVerify ( "function t f() { return [ ]; };" );
630 }
TEST_CASE(ConstVectExpr)631 TEST_CASE ( ConstVectExpr )
632 {
633     ParseAndVerify ( "function t f() { return [ 1, 2, 3 ]; };" );
634 }
635 
TEST_CASE(BoolExpr_True)636 TEST_CASE ( BoolExpr_True )
637 {
638     ParseAndVerify ( "function t f() { return true; };" );
639 }
TEST_CASE(BoolExpr_False)640 TEST_CASE ( BoolExpr_False )
641 {
642     ParseAndVerify ( "function t f() { return false; };" );
643 }
644 
TEST_CASE(NegateExpr_Ident)645 TEST_CASE ( NegateExpr_Ident )
646 {
647     ParseAndVerify ( "function t f() { return -a; };" );
648 }
TEST_CASE(NegateExpr_Int)649 TEST_CASE ( NegateExpr_Int )
650 {
651     ParseAndVerify ( "function t f() { return -1; };" );
652 }
TEST_CASE(NegateExpr_Float)653 TEST_CASE ( NegateExpr_Float )
654 {
655     ParseAndVerify ( "function t f() { return -1.0; };" );
656 }
657 
TEST_CASE(FuncExpr_NoSchemaNoFactNoParms)658 TEST_CASE ( FuncExpr_NoSchemaNoFactNoParms )
659 {
660     ParseAndVerify ( "function t f() { return f(); };" );
661 }
TEST_CASE(FuncExpr_NoSchemaFactNoParms)662 TEST_CASE ( FuncExpr_NoSchemaFactNoParms )
663 {
664     ParseAndVerify ( "function t f() { return f<1>(); };" );
665 }
TEST_CASE(FuncExpr_NoSchemaNoFactParms)666 TEST_CASE ( FuncExpr_NoSchemaNoFactParms )
667 {
668     ParseAndVerify ( "function t f() { return f(1); };" );
669 }
TEST_CASE(FuncExpr_NoSchemaFactParms)670 TEST_CASE ( FuncExpr_NoSchemaFactParms )
671 {
672     ParseAndVerify ( "function t f() { return f<a, b>(c, d); };" );
673 }
TEST_CASE(FuncExpr_Version)674 TEST_CASE ( FuncExpr_Version )
675 {
676     ParseAndVerify ( "function t f() { return f#1<a, b>(c, d); };" );
677 }
678 
TEST_CASE(PhysicalIdent)679 TEST_CASE ( PhysicalIdent )
680 {
681     ParseAndVerify ( "function t f() { return .b; };" );
682 }
683 
684 // Version 2
685 
TEST_CASE(VersionOther)686 TEST_CASE ( VersionOther )
687 {
688     REQUIRE ( ! SchemaParser () . ParseString ( "version 3.14; $" ) );
689 }
690 
TEST_CASE(Version2_Decl1)691 TEST_CASE ( Version2_Decl1 )
692 {
693     ParseAndVerify ( "version 2; include \"qq\";" );
694 }
695 
TEST_CASE(View_InVers1)696 TEST_CASE ( View_InVers1 )
697 {
698     REQUIRE ( ! SchemaParser () . ParseString ( "view X#1 < T t > {};" ) );
699 }
700 
TEST_CASE(Decls_1_And_2)701 TEST_CASE ( Decls_1_And_2 )
702 {
703     ParseAndVerify ( "version 2;  include \"qq\"; view X#1< T t > { U8 p = 1; };" );
704 }
705 
TEST_CASE(View_OneParam_OneStmt)706 TEST_CASE ( View_OneParam_OneStmt )
707 {
708     ParseAndVerify ( "version 2; view X#1 < T t > { U8 p = 1; };" );
709 }
710 
TEST_CASE(View_Params_Stmts)711 TEST_CASE ( View_Params_Stmts )
712 {
713     ParseAndVerify ( "version 2; view X#1 < T1 t1, T2 t2 > { U8 p = 1; ; column U32 c = p; };" );
714 }
715 
TEST_CASE(View_OneParent)716 TEST_CASE ( View_OneParent )
717 {
718     ParseAndVerify ( "version 2; view X#1 < T t > = V < t > { U8 p = 1; };" );
719 }
720 
TEST_CASE(View_TwoParents)721 TEST_CASE ( View_TwoParents )
722 {
723     ParseAndVerify ( "version 2; view X#1 < T t > = V#1<t>,W<t> { U8 p = 1; };" );
724 }
725 
TEST_CASE(View_OneParam_EmptyBody)726 TEST_CASE ( View_OneParam_EmptyBody )
727 {
728     ParseAndVerify ( "version 2; view X#1 < T t > {};" );
729 }
730 
TEST_CASE(View_NoPhysicalColumns)731 TEST_CASE ( View_NoPhysicalColumns )
732 {
733     REQUIRE ( ! SchemaParser () . ParseString ( "version 2; view X#1 < T t > { column U8 .PHYS = 1; };" ) );
734 }
735 
TEST_CASE(View_MemberExpression)736 TEST_CASE ( View_MemberExpression )
737 {
738     ParseAndVerify ( "version 2; table T#1 { column U8 c1 = 1; }; view W#1 <T t> { column U8 c2 = t . c1; }" );
739 }
740 
TEST_CASE(View_JoinExpression)741 TEST_CASE ( View_JoinExpression )
742 {
743     ParseAndVerify ( "version 2; table T#1 { column U8 c1 = 1; }; view W#1 <T t> { column U8 c2 = t [ 1 ] . c1; }" );
744 }
745 
746 //////////////////////////////////////////// Main
747 #include <kapp/args.h>
748 #include <kfg/config.h>
749 #include <klib/out.h>
750 
751 extern "C"
752 {
753 
KAppVersion(void)754 ver_t CC KAppVersion ( void )
755 {
756     return 0x1000000;
757 }
758 
759 const char UsageDefaultName[] = "wb-test-schema-parser";
760 
UsageSummary(const char * progname)761 rc_t CC UsageSummary (const char * progname)
762 {
763     return KOutMsg ( "Usage:\n" "\t%s [options] -o path\n\n", progname );
764 }
765 
Usage(const Args * args)766 rc_t CC Usage( const Args* args )
767 {
768     return 0;
769 }
770 
KMain(int argc,char * argv[])771 rc_t CC KMain ( int argc, char *argv [] )
772 {
773     return SchemaParserTestSuite(argc, argv);
774 }
775 
776 }
777 
778