Commits

Kirill Simonov committed 66c2a75

Moved regression tests to test/regress directory.

Comments (0)

Files changed (32)

test/input/format.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: Formatting Output Data
-id: format
-tests:
-
-- title: Supported Output Formats
-  tests:
-  - uri: /school/:json
-  - uri: /school/:csv
-  - uri: /school/:txt
-  - uri: /school/:html
-  - uri: /school/:unknown
-    expect: 400
-
-- title: Format Selection by `Accept`
-  tests:
-  - uri: /school
-    headers:
-      Accept: application/json
-  - uri: /school
-    headers:
-      Accept: text/csv
-  - uri: /school
-    headers:
-      Accept: text/plain
-  - uri: /school
-    headers:
-      Accept: text/html
-
-- title: The `AS` Decorator
-  tests:
-    - uri: /(school :as 'List of Schools')
-            {name :as Name, count(department) :as '# of Departments'}
-            /:json
-    - uri: /(school :as 'List of Schools')
-            {name :as Name, count(department) :as '# of Departments'}
-            /:csv
-    - uri: /(school :as 'List of Schools')
-            {name :as Name, count(department) :as '# of Departments'}
-            /:txt
-    - uri: /(school :as 'List of Schools')
-            {name :as Name, count(department) :as '# of Departments'}
-            /:html
-
-- title: Data Types
-  tests:
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-          /:json
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-          /:csv
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-          /:txt
-  - uri: /{null(),true(),false(),60,2.125,271828e-5,'HTSQL',date('2010-04-15')}
-          /:html
-
-- title: No Rows
-  tests:
-  - uri: /school?false()/:json
-  - uri: /school?false()/:csv
-  - uri: /school?false()/:txt
-  - uri: /school?false()/:html
-

test/input/library.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: Standard Data Types, Functions, and Operations
-id: library
-tests:
-
-########################################################################
-
-- title: Literals
-  tests:
-
-  # Untyped literals, implicitly converted to string
-  - uri: /{null(), '', 'HTSQL'}
-
-  # Boolean values
-  - uri: /{true(), false()}
-  - uri: /{boolean('true'), boolean('false')}
-  # Invalid Boolean literals
-  - uri: /boolean('')
-    expect: 400
-  - uri: /boolean('yes')
-    expect: 400
-
-  # String values
-  - uri: /{'', 'HTSQL', 'O''Reilly',
-           '%ce%bb%cf%8c%ce%b3%ce%bf%cf%82',
-           '$-b \pm \sqrt{b^2 - 4ac} \over 2a$'}
-  - uri: /{string('832040')}
-
-  # Integer values
-  - uri: /{0, 7, -97, 3571}
-  - uri: /{integer('4862'), integer('-9694845')}
-  # 64-bit signed integers
-  - uri: /{integer('-9223372036854775808'),
-           integer('9223372036854775807')}
-  # Invalid integer literal
-  - uri: /{integer('2.5e1')}
-    expect: 400
-  # Out of range
-  - uri: /{18446744073709551616}
-    expect: 400
-
-  # Decimal values
-  - uri: /{1.0, -2.5, 0.875}
-  - uri: /{decimal('1E-10')}
-  # Arbitrary length
-  - uri: /{4154781481226426191177580544000000.808017424794512875886459904961710757005754368000000000}
-  # Invalid decimal literals
-  - uri: /{decimal('vingt-cinq')}
-    expect: 400
-
-  # Float values
-  - uri: /{0e0, -57721e-5, 36288e2}
-  - uri: /{float('2147483647')}
-  # Invalid float literal
-  - uri: /float('vingt-cinq')
-    expect: 400
-  # Infinity
-  - uri: /{1e1024}
-    expect: 400
-  - uri: /{float('inf')}
-    expect: 400
-
-  # Date values
-  - uri: /{date('2010-04-15')}
-  # Invalid date
-  - uri: /date('2010-13-07')
-    expect: 400
-
-########################################################################
-
-- title: Logical and Comparison Operators
-  tests:
-
-  # Boolean literals
-  - uri: /{true(), false()}
-  # Boolean conversion
-  - uri: /{boolean(null()), boolean('true'), boolean('false')}
-  - uri: /{boolean(integer(null())), boolean(0.0), boolean(1e0)}
-  - uri: /{boolean(string(null())),
-           boolean(string('')),
-           boolean(string('FALSE'))}
-  - uri: /{boolean(date(null())), boolean(date('2010-04-15'))}
-  # AND, OR, NOT
-  - uri: /{true()&true(), true()&false(), false()&true(), false()&false()}
-  - uri: /{true()|true(), true()|false(), false()|true(), false()|false()}
-  - uri: /{!true(), !false()}
-  - uri: /{null()&true(), null()&false(), null()&null()}
-  - uri: /{null()|true(), null()|false(), null()|null()}
-  - uri: /{!null()}
-  # Is NULL
-  - uri: /{is_null(null()), is_null('NULL'), is_null(0)}
-
-  # Equality
-  - uri: /{true()=true(), 1=1, 'HTSQL'='HTSQL',
-           date('2010-04-15')=date('2010-04-15')}
-  - uri: /{true()!=false(), 1!=0, 'HTSQL'!='PITA',
-           date('2010-04-15')!=date('1991-08-20')}
-  - uri: /{true()!=true(), 1!=1, 'HTSQL'!='HTSQL',
-           date('2010-04-15')!=date('2010-04-15')}
-  - uri: /{true()=false(), 1=0, 'HTSQL'='PITA',
-           date('2010-04-15')=date('1991-08-20')}
-  # IN
-  - uri: /{5={2,3,5,7}, 'HTSQL'!={'ISBL','SQUARE','QUEL'}}
-  - uri: /{5!={2,3,5,7}, 'HTSQL'={'ISBL','SQUARE','QUEL'}}
-  # NULL and Total Equality
-  - uri: /{1=null(), 1!=null(), null()=null(), null()!=null()}
-  - uri: /{false()={false(),null()}, true()={false(),null()},
-           false()!={false(),null()}, false()!={true(),null()}}
-  - uri: /{null()={true(),false()}, null()!={true(),false()}}
-  - uri: /{1==1, 1!==0, 1==null(), 1!==null(),
-           null()==null(), null()!==null()}
-  # Coercion
-  - uri: /{7=0.7e1, '13'=13.0, '13'!=='13.0'}
-  # Inadmissible operands
-  - uri: /{true()=1}
-    expect: 400
-  - uri: /{'cinq'!=4.9}
-    expect: 400
-  - uri: /{date('2010-04-15')==1991}
-    expect: 400
-
-  # Comparison
-  - uri: /{1<10, 7.0<=7.0, 'omega'>'alpha',
-           date('2010-04-15')>=date('1991-08-20')}
-  - uri: /{1>=10, 7.0>7.0, 'omega'<='alpha',
-           date('2010-04-15')<date('1991-08-20')}
-  # NULL
-  - uri: /{0<null(), ''>null(), null()>=null()}
-  # Coercion
-  - uri: /{175e-2>'875e-3', '2010-04-15'>=date('1991-08-20')}
-  # Inadmissible operands
-  - uri: /{false()<true()}
-    expect: 400
-  - uri: /{'cinq'>4.9}
-    expect: 400
-  - uri: /{date('2010-04-15')>=1991}
-    expect: 400
-
-  # If NULL and NULL If
-  - uri: /{if_null('Victor', 'William'),
-           if_null(null(), 'William'),
-           if_null('Victor', null()),
-           if_null(null(), null())}
-  - uri: /{null_if('George', 'George'),
-           null_if('George', 'Harry'),
-           null_if(null(),  'Harry'),
-           null_if('George', null()),
-           null_if(null(), null())}
-  # Coercion
-  - uri: /{if_null(1, 0.1e1), null_if(1, 0.1e1)}
-  # Inadmissible operands
-  - uri: /{if_null('cinq', 5)}
-    expect: 400
-  - uri: /{null_if('cinq', 5)}
-    expect: 400
-  - uri: /{if_null(date('2010-04-15'),1991)}
-    expect: 400
-  - uri: /{null_if(date('2010-04-15'),1991)}
-    expect: 400
-
-  # If and Switch
-  - uri: /{if(true(), 'then'),
-           if(false(), 'then'),
-           if(null(), 'then')}
-  - uri: /{if(true(), 'then', 'else'),
-           if(false(), 'then', 'else'),
-           if(null(), 'then', 'else')}
-  - uri: /{if(7=0, 'none', 7=1, 'one', 7=2, 'two', 'many')}
-  - uri: /{switch(1, 1, 'George', 2, 'Harry'),
-           switch(2, 1, 'George', 2, 'Harry'),
-           switch(3, 1, 'George', 2, 'Harry')}
-  - uri: /{switch(1, 1, 'George', 2, 'Harry', 'Edward'),
-           switch(2, 1, 'George', 2, 'Harry', 'Edward'),
-           switch(3, 1, 'George', 2, 'Harry', 'Edward')}
-  # Coercion
-  - uri: /{if(true(), 1, 0e0)}
-  - uri: /{switch(date('2010-04-15'),
-                  '1991-08-20', 'WWW',
-                  '2010-04-15', 'HTSQL')}
-  # Inadmissible operands
-  - uri: /{if('', 'then', 'else')}
-    expect: 400
-  - uri: /{switch(1, date('2010-04-15'), 1, date('1991-08-20'), 2)}
-    expect: 400
-  - uri: /{switch(1, 1, 'George', 2, false())}
-    expect: 400
-
-########################################################################
-
-- title: Numeric Functions and Operators
-  tests:
-
-  # Conversion
-  - uri: /{integer(null()), integer('60'), integer(60)}
-  - uri: /{decimal(null()), decimal('2.125'), decimal(2.125)}
-  - uri: /{float(null()), float('271828e-5'), float('271828e-5')}
-  - uri: /{integer(2.125), integer(271828e-5)}
-  - uri: /{decimal(60), decimal(271828e-5)}
-  - uri: /{float(60), float(2.125)}
-  - uri: /{integer(string('60'))}
-  - uri: /{decimal(string('2.125'))}
-  - uri: /{float(string('271828e-5'))}
-  # Inadmissible operand
-  - uri: /{integer('cinq')}
-    expect: 400
-  - uri: /{decimal(true())}
-    expect: 400
-  - uri: /{float(date('2010-04-15'))}
-    expect: 400
-  # Not a number
-  - uri: /{integer(string('zero'))}
-    ifdef: [sqlite, mysql]
-  - uri: /{float(string('zero'))}
-    ifdef: [sqlite, mysql]
-  - uri: /{integer(string('cinq'))}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  # Integer overflow
-  - uri: /{integer(4294967296.0)}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{integer(1.8446744073709552e+19)}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{integer(4294967296.0),
-           integer(1.8446744073709552e+19)}
-    ifdef: [sqlite, mysql]
-
-  # Arithmetics
-  - uri: /{+7, -7, +2.125, -2.125, +271828e-5, -271828e-5}
-  - uri: /{7920+9504, 7.25+0.875, 120205e-5+57721e-5}
-  - uri: /{7920-9504, 7.25-0.875, 120205e-5-57721e-5}
-  - uri: /{7920*9504, 7.25*0.875, 120205e-5*57721e-5}
-  - uri: /{7920/9504, 7.25/0.875, 120205e-5/57721e-5}
-  # Coercion
-  - uri: /{7+2.125, 7+271828e-5, 2.125+271828e-5}
-  - uri: /{7-2.125, 7-271828e-5, 2.125-271828e-5}
-  - uri: /{7*2.125, 7*271828e-5, 2.125*271828e-5}
-  - uri: /{7/2.125, 7/271828e-5, 2.125/271828e-5}
-  # Inadmissible operands
-  - uri: /{'cinq'+7}
-    expect: 400
-  - uri: /{2.125-date('2010-04-15')}
-    expect: 400
-  - uri: /{true()/271828e-5}
-    expect: 400
-  # Integer overflow
-  - uri: /{7*2147483647}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{9223372036854775807+1}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{7*2147483647, 9223372036854775807+1}
-    ifdef: [sqlite, mysql]
-  # Division by zero
-  - uri: /{7/0}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{7/0.0}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{7/0e0}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{7/0, 7/0.0, 7/0e0}
-    ifdef: [sqlite, mysql]
-
-  # Rounding
-  - uri: /{round(3272.78125,2)}
-  - uri: /{round(3272.78125,-2)}
-    ifndef: sqlite
-  - uri: /{round(3272.78125), round(271828e-5)}
-  # Coercion
-  - uri: /{round(9973)}
-  - uri: /{round(9973,-2)}
-    ifndef: sqlite
-  # Inadmissible operand
-  - uri: /{round(271828e-5,2)}
-    expect: 400
-    ifndef: sqlite
-
-########################################################################
-
-- title: String Functions and Operators
-  tests:
-
-  # Conversion
-  - uri: /{string(null()), string('OMGWTFBBQ')}
-  - uri: /{string(true()), string(false())}
-  - uri: /{string(60), string(2.125), string(-57721e-5)}
-  - uri: /{string(date('2010-04-15'))}
-
-  # Length
-  - uri: /{length(''), length('OMGWTFBBQ')}
-  - uri: /{length(null())}
-  # Inadmissible operand
-  - uri: /{length(date(2010-04-15))}
-    expect: 400
-
-  # Concatenation
-  - uri: /{'OMG'+'WTF'+'BBQ'}
-  - uri: /{null()+'LOL', 'LOL'+null(),
-           string(null())+string(null())}
-  # Inadmissible operands
-  - uri: /{string('LOL')+7}
-    expect: 400
-
-  # Contains
-  - uri: /{'OMGWTFBBQ'~'wtf', 'OMGWTFBBQ'!~'LOL'}
-  - uri: /{'OMGWTFBBQ'!~'wtf', 'OMGWTFBBQ'~'LOL'}
-  - uri: /{null()~'LOL', 'LOL'~null(), null()~null()}
-
-  # Slicing
-  - uri: /{head('OMGWTFBBQ'), head('OMGWTFBBQ',3), head('OMGWTFBBQ',-3)}
-  - uri: /{tail('OMGWTFBBQ'), tail('OMGWTFBBQ',3), tail('OMGWTFBBQ',-3)}
-  - uri: /{head('OMGWTFBBQ',0), tail('OMGWTFBBQ',0)}
-  - uri: /{head(null()), tail(null()),
-           head('OMGWTFBBQ',null()), tail('OMGWTFBBQ',null())}
-  - uri: /{slice('OMGWTFBBQ',3,6), slice('OMGWTFBBQ',3,-3),
-           slice('OMGWTFBBQ',-6,6), slice('OMGWTFBBQ',-6,-3)}
-  - uri: /{slice('OMGWTFBBQ',0,0), slice('OMGWTFBBQ',6,3),
-           slice('OMGWTFBBQ',10,13), slice('OMGWTFBBQ',-3,-6)}
-  - uri: /{slice(null(),3,-3), slice('OMGWTGBBQ',null(),null()),
-           slice('OMGWTFBBQ',-3,null()), slice('OMGWTFBBQ',null(),3)}
-  - uri: /{at('OMGWTFBBQ',0), at('OMGWTFBBQ',3), at('OMGWTFBBQ',-3)}
-  - uri: /{at('OMGWTFBBQ',3,3), at('OMGWTFBBQ',6,-3),
-           at('OMGWTFBBQ',-3,3), at('OMGWTFBBQ',-12,6)}
-  - uri: /{at('OMGWTFBBQ',10), at('OMGWTFBBQ',0,-3)}
-  - uri: /{at(null(),3), at('OMGWTFBBQ',null(),3), at('OMGWTFBBQ',3,null())}
-
-  # Transformations
-  - uri: /{upper('lol'), lower('LOL')}
-  - uri: /{trim('  LOL  '), ltrim('  LOL  '), rtrim('  LOL  ')}
-  - uri: /{replace('OMGWTFBBQ','WTF','LOL')}
-  - uri: /{replace('OMGWTFBBQ','wtf','LOL'),
-           replace('OMGWTFBBQ','WTF','lol')}
-  - uri: /{replace('floccinaucinihilipilification','ili','LOL')}
-  - uri: /{replace('OMGWTFBBQ','','LOL'),
-           replace('OMGWTFBBQ','WTF','')}
-  - uri: /{replace(null(),'WTF','LOL'),
-           replace('OMGWTFBBQ',null(),'LOL'),
-           replace('OMGWTFBBQ','WTF',null())}
-
-########################################################################
-
-- title: Date Functions and Operators
-  tests:
-
-  # Conversion
-  - uri: /{date(null()), date('2010-04-15')}
-  # Inadmissible operand
-  - uri: /{date('2010-13-07')}
-    expect: 400
-  - uri: /{date(true())}
-    expect: 400
-  - uri: /{date(7)}
-    expect: 400
-  # Not a date
-  - uri: /{date(string('birthday'))}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{date(string('2010-13-07'))}
-    expect: 409
-    ignore: true
-    ifdef: pgsql
-  - uri: /{date(string('birthday')),
-           date(string('2010-13-07'))}
-    ifdef: [sqlite, mysql]
-
-  # Construction
-  - uri: /{today()}
-    ignore: true
-  - uri: /{date(2010,4,15), date(2010,3,46), date(2011,-8,15)}
-
-  # Components
-  - uri: /{year(date('2010-04-15')),
-           month(date('2010-04-15')),
-           day(date('2010-04-15'))}
-
-  # Arithmetics
-  - uri: /{date('1991-08-20')+6813,
-           date('2010-04-15')-6813,
-           date('2010-04-15')-date('1991-08-20')}
-
-########################################################################
-
-- title: Aggregate functions
-  tests:
-
-  # Exists, Every, Count
-  - uri: /course?department='lang'
-  - uri: /{exists(course?department='lang'),
-           every(course?department='lang'),
-           count(course?department='lang')}
-  # Applied to an empty set
-  - uri: /course?department='str'
-  - uri: /{exists(course?department='str'),
-           every(course?department='str'),
-           count(course?department='str')}
-  # Applied to all-TRUE, all-FALSE, mixed sets
-  - uri: /course{department,number,credits,credits>3}
-                ?department={'me','mth','phys'}
-  - uri: /{exists(course{credits>3}?department='me'),
-           every(course{credits>3}?department='me'),
-           count(course{credits>3}?department='me')}
-  - uri: /{exists(course{credits>3}?department='mth'),
-           every(course{credits>3}?department='mth'),
-           count(course{credits>3}?department='mth')}
-  - uri: /{exists(course{credits>3}?department='phys'),
-           every(course{credits>3}?department='phys'),
-           count(course{credits>3}?department='phys')}
-  # Coercion
-  - uri: /department{code,school,boolean(school)}
-  - uri: /{exists(department{school}),
-           every(department{school}),
-           count(department{school})}
-  # Singular operand
-  - uri: /{exists(true())}
-    expect: 400
-  - uri: /{every(true())}
-    expect: 400
-  - uri: /{count(true())}
-    expect: 400
-
-  # Min, Max
-  - uri: /course{number,credits}?department='be'
-  - uri: /{min(course{credits}?department='be'),
-           max(course{credits}?department='be')}
-  # Applied to an empty set
-  - uri: /course?department='str'
-  - uri: /{min(course{credits}?department='str'),
-           max(course{credits}?department='str')}
-  # Non-numeric operands
-  - uri: /{min(student.dob), max(student.dob)}
-  - uri: /{min(student.name), max(student.name)}
-  # Inadmissible operand
-  - uri: /{min(student.is_active), max(student.is_active)}
-    expect: 400
-
-  # Sum, Avg
-  - uri: /{sum(course{credits}?department='be'),
-           count(course{credits}?department='be'),
-           avg(course{credits}?department='be')}
-  # Applied to an empty set
-  - uri: /{sum(course{credits}?department='str'),
-           count(course{credits}?department='str'),
-           avg(course{credits}?department='str')}
-  # Inadmissible operands
-  - uri: /{sum(student.dob)}
-    expect: 400
-  - uri: /{avg(student.name)}
-    expect: 400
-
-########################################################################
-
-- title: Table functions and operators
-  tests:
-
-  # Joining
-  # 1 - N
-  - uri: /school.program
-  - uri: /school.department
-  # N - 1
-  - uri: /program.school
-  - uri: /department.school
-  # 1 - 1
-  - uri: /instructor.confidential
-  - uri: /confidential.instructor
-  # Cross join
-  - uri: /school.fiber(school)
-  # Fiber join
-  - uri: /department.fiber(program,school)
-  - uri: /classification.fiber(classification,code,part_of)
-            {part_of, code}
-  # Context
-  - uri: /school.fiber(school){root().school.code, this().code}
-  # Invalid link
-  - uri: /student.instructor
-    expect: 400
-
-  # Filtering
-  - uri: /school?code='mus'
-  - uri: /student?!is_active
-  # Coercion
-  - uri: /department?school
-
-  # Sorting
-  - uri: /department.sort(name)
-  - uri: /department.sort(name+)
-  - uri: /department.sort(name-)
-  # NULL
-  - uri: /department.sort(school+)
-  - uri: /department.sort(school-)
-  # Combined with joining
-  - uri: /school.department.sort(code+)
-  - uri: /school.sort(code+).department.sort(code+)
-  # Multiple arguments
-  - uri: /course.sort(credits-,number+)?department='stdart'
-
-  # Limiting
-  - uri: /course.limit(9)
-  - uri: /course.limit(3,6)
-  # Combined with sort
-  - uri: /course.sort(credits+).limit(9)
-  - uri: /course.limit(9).sort(credits+)
-  - uri: /course.sort(credits-).limit(9).sort(number-)
-
-  # Selecting
-  - uri: /school{name}
-  - uri: /department{school.name, name}
-  - uri: /school{*}
-  - uri: /department{school.*, *}
-
-########################################################################
-
-- title: Decorators
-  tests:
-
-  # AS decorator
-  - uri: /(school :as 'List of Schools')
-  - uri: /school{name :as Name}
-  - uri: /(school :as 'List of Schools')
-            {name :as Name, count(department) :as '# of Departments'}
-
-  # Direction decorator
-  - uri: /school{name+}
-  - uri: /course{credits-, number+, title}?department='stdart'
-

test/input/mysql.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: MySQL regression tests
-id: mysql
-output: test/output/mysql.yaml
-tests:
-
-- title: Remove any existing regression database
-  id: drop-mysql
-  tests:
-  - connect: &admin-connect
-      engine: mysql
-      database: mysql
-      username: ${MYSQL_ADMIN_USERNAME}
-      password: ${MYSQL_ADMIN_PASSWORD}
-      host: ${MYSQL_HOST}
-      port: ${MYSQL_PORT}
-    sql: !environ |
-        DROP DATABASE `${MYSQL_DATABASE}`;
-    #autocommit: true
-    ignore: true
-  - connect: *admin-connect
-    sql: !environ |
-        DROP USER `${MYSQL_USERNAME}`;
-- title: Deploy the regression database
-  id: create-mysql
-  tests:
-  - connect: *admin-connect
-    sql: !environ |
-        CREATE DATABASE `${MYSQL_DATABASE}`
-            CHARACTER SET utf8 COLLATE utf8_general_ci;
-        CREATE USER `${MYSQL_USERNAME}`
-            IDENTIFIED BY '${MYSQL_PASSWORD}';
-        GRANT ALL PRIVILEGES
-            ON `${MYSQL_DATABASE}`.* TO `${MYSQL_USERNAME}`;
-    #autocommit: true
-  - connect: &connect
-      engine: mysql
-      database: ${MYSQL_DATABASE}
-      username: ${MYSQL_USERNAME}
-      password: ${MYSQL_PASSWORD}
-      host: ${MYSQL_HOST}
-      port: ${MYSQL_PORT}
-    sql-include: test/sql/regress-mysql.sql
-
-- title: Run the test collection
-  id: test-mysql
-  tests:
-  - define: mysql
-  - db: *connect
-  # The Regression Schema
-  - include: test/input/schema.yaml
-  # Examples from the Tutorial
-  - include: test/input/tutorial.yaml
-  # Standard Data Types, Functions, and Operations
-  - include: test/input/library.yaml
-  # Edge Cases of HTSQL-to-SQL Translation
-  - include: test/input/translation.yaml
-  # Formatting Output Data
-  - include: test/input/format.yaml
-

test/input/pgsql.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: PostgreSQL regression tests
-id: pgsql
-output: test/output/pgsql.yaml
-tests:
-
-- title: Remove any existing regression database
-  id: drop-pgsql
-  tests:
-  - connect: &admin-connect
-      engine: pgsql
-      database: postgres
-      username: ${PGSQL_ADMIN_USERNAME}
-      password: ${PGSQL_ADMIN_PASSWORD}
-      host: ${PGSQL_HOST}
-      port: ${PGSQL_PORT}
-    sql: !environ |
-        DROP DATABASE IF EXISTS "${PGSQL_DATABASE}";
-        DROP ROLE IF EXISTS "${PGSQL_USERNAME}";
-    autocommit: true
-
-- title: Deploy the regression database
-  id: create-pgsql
-  tests:
-  - connect: *admin-connect
-    sql: !environ |
-        CREATE DATABASE "${PGSQL_DATABASE}" WITH ENCODING = 'UTF-8';
-        CREATE ROLE "${PGSQL_USERNAME}" WITH LOGIN PASSWORD '${PGSQL_PASSWORD}';
-        ALTER DATABASE "${PGSQL_DATABASE}" OWNER TO "${PGSQL_USERNAME}";
-    autocommit: true
-  - connect: &connect
-      engine: pgsql
-      database: ${PGSQL_DATABASE}
-      username: ${PGSQL_USERNAME}
-      password: ${PGSQL_PASSWORD}
-      host: ${PGSQL_HOST}
-      port: ${PGSQL_PORT}
-    sql-include: test/sql/regress-pgsql.sql
-
-- title: Run the test collection
-  id: test-pgsql
-  tests:
-  - define: pgsql
-  - db: *connect
-  # The Regression Schema
-  - include: test/input/schema.yaml
-  # Examples from the Tutorial
-  - include: test/input/tutorial.yaml
-  # Standard Data Types, Functions, and Operations
-  - include: test/input/library.yaml
-  # Edge Cases of HTSQL-to-SQL Translation
-  - include: test/input/translation.yaml
-  # Formatting Output Data
-  - include: test/input/format.yaml
-

test/input/routine.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: HTSQL-CTL Command-Line Tool
-id: routine
-output: test/output/routine.yaml
-tests:
-- ctl: []
-- ctl: [help]
-- ctl: [help, help]
-# FIXME: need comprehensive tests for each routine.
-

test/input/schema.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: The Regression Schema
-id: schema
-tests:
-
-- title: Tables
-  tests:
-  # Administrative Directory
-  - uri: /school
-  - uri: /department
-  - uri: /program
-  - uri: /course
-  # Instructor Directory
-  - uri: /instructor
-  - uri: /confidential
-  - uri: /appointment
-  # Class Directory
-  - uri: /semester
-  - uri: /class
-  # Enrollment Directory
-  - uri: /student
-  - uri: /enrollment
-  # Requirement Directory
-  - uri: /prerequisite
-  - uri: /classification
-  - uri: /course_classification
-  - uri: /program_requirement
-
-- title: Links
-  tests:
-  # FIXME: rewrite using locators once we have them.
-
-  # School -> Department
-  - uri: /(school?code='art').department
-  # School -> Program
-  - uri: /(school?code='art').program
-  # School -> Student (via Program)
-  - uri: /(school?code='art').student
-
-  # Department -> School (singular, optional)
-  - uri: /(department?code='ee').school
-  # Department -> Course
-  - uri: /(department?code='ee').course
-  # Department -> Appointment
-  - uri: /(department?code='ee').appointment
-  # Department -> Class (via Course)
-  - uri: /(department?code='ee').class
-
-  # Program -> School (parental)
-  - uri: /(program?school='eng'&code='umech').school
-  # Program -> Program (singular, self-referencial)
-  - uri: /(program?school='eng'&code='umech').part_of
-  # Program -> Program (reverse self-referential)
-  # FIXME: broken! No way to indicate a reverse self-referential link.
-  # The query below, in fact, produces a direct self-referential link.
-  - uri: /(program?school='eng'&code='umech').program
-  # Program -> Student
-  - uri: /(program?school='eng'&code='umech').student
-  # Program -> Program Requirement
-  - uri: /(program?school='eng'&code='umech').program_requirement
-
-  # Course -> Department (parental)
-  - uri: /(course?department='psych'&number=610).department
-  # Course -> Class
-  - uri: /(course?department='psych'&number=610).class
-  # Course -> Prerequisite
-  # FIXME: broken! Cannot choose between on_course and of_course links;
-  # need a mechanism to select a desired link among ambiguous links.
-  - uri: /(course?department='psych'&number=610).prerequisite
-    expect: 400
-  # Course -> Course Classification
-  - uri: /(course?department='psych'&number=610).course_classification
-
-  # Instructor -> Confidential (singular, optional)
-  - uri: /(instructor?code='kcavallaro').confidential
-  # Instructor -> Appointment
-  - uri: /(instructor?code='kcavallaro').appointment
-  # Instructor -> Class
-  - uri: /(instructor?code='kcavallaro').class
-
-  # Confidential -> Instructor
-  - uri: /(confidential?instructor='tobrien21').instructor
-
-  # Appointment -> Department (parental)
-  - uri: /(appointment?department='eng'&instructor='wyu112').department
-  # Appointment -> Instructor (parental)
-  - uri: /(appointment?department='eng'&instructor='wyu112').instructor
-
-  # Semester -> Class
-  - uri: /(semester?year=2010&season='fall').class
-
-  # Class -> Department (grand-parental, via Course)
-  - uri: /(class?class_seq=10086).department
-  # Class -> Course (parental)
-  - uri: /(class?class_seq=10086).course
-  # Class -> Semester (parental)
-  - uri: /(class?class_seq=10086).semester
-  # Aliases for Class -> Semester
-  - uri: /(class?class_seq=10086).year
-  - uri: /(class?class_seq=10086).season
-  # Class -> Instructor (singular, optional)
-  - uri: /(class?class_seq=10086).instructor
-  # Class -> Enrollment
-  - uri: /(class?class_seq=10086).enrollment
-
-  # Student -> School (singular, optional, via Program)
-  - uri: /(student?number=25371).school
-  # Student -> Program (singular, optional)
-  - uri: /(student?number=25371).program
-  # Student -> Enrollment
-  - uri: /(student?number=25371).enrollment
-
-  # Enrollment -> Student (parental)
-  - uri: /(enrollment?student=92039&class=10071).student
-  # Enrollment -> Class (parental)
-  - uri: /(enrollment?student=92039&class=10071).class
-
-  # Prerequisite -> Department (grand-parental, via Course, using of_department)
-  - uri: /(prerequisite?of_department='capmrk'&of_course=818
-                       &on_department='acc'&on_course=315).of_department
-  # Prerequisite -> Department (grand-parental, via Course, using on_department)
-  - uri: /(prerequisite?of_department='capmrk'&of_course=818
-                       &on_department='acc'&on_course=315).on_department
-  # Prerequisite -> Department (ambiguous)
-  - uri: /(prerequisite?of_department='capmrk'&of_course=818
-                       &on_department='acc'&on_course=315).department
-    expect: 400
-  # Prerequisite -> Course (parental, using of_course)
-  - uri: /(prerequisite?of_department='capmrk'&of_course=818
-                       &on_department='acc'&on_course=315).of_course
-  # Prerequisite -> Course (parental, using on_course)
-  - uri: /(prerequisite?of_department='capmrk'&of_course=818
-                       &on_department='acc'&on_course=315).on_course
-  # Prerequisite -> Course (ambiguous)
-  - uri: /(prerequisite?of_department='capmrk'&of_course=818
-                       &on_department='acc'&on_course=315).course
-    expect: 400
-
-  # Classification -> Classification (singular, self-referencial)
-  - uri: /(classification?code='modlanguage').part_of
-  # Classification -> Classification (reverse self-referential)
-  # FIXME: broken! No way to indicate a reverse self-referential link.
-  # The query below, in fact, produces a direct self-referential link.
-  - uri: /(classification?code='modlanguage').classification
-  # Classification -> Course Classification
-  - uri: /(classification?code='modlanguage').course_classification
-  # Classification -> Program Requirement
-  - uri: /(classification?code='modlanguage').program_requirement
-
-  # Course Classification -> Department (grand-parental, via Course)
-  - uri: /(course_classification?department='be'&course=112
-                                &classification='begeneral').department
-  # Course Classification -> Course (parental)
-  - uri: /(course_classification?department='be'&course=112
-                                &classification='begeneral').course
-  # Course Classification -> Classification (parental)
-  - uri: /(course_classification?department='be'&course=112
-                                &classification='begeneral').classification
-
-  # Program Requirement -> School (grand-parental, via Program)
-  - uri: /(program_requirement?school='bus'&program='uacct'
-                              &classification='accounting').school
-  # Program Requirement -> Program (parental)
-  - uri: /(program_requirement?school='bus'&program='uacct'
-                              &classification='accounting').program
-  # Program Requirement -> Classification (parental)
-  - uri: /(program_requirement?school='bus'&program='uacct'
-                              &classification='accounting').classification
-

test/input/sqlite.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: SQLite regression tests
-id: sqlite
-output: test/output/sqlite.yaml
-tests:
-
-- title: Remove any existing regression database
-  id: drop-sqlite
-  tests:
-  - rmdir: ${SQLITE_DIRECTORY}
-
-- title: Deploy the regression database
-  id: create-sqlite
-  tests:
-  - mkdir: ${SQLITE_DIRECTORY}
-  - connect: &connect
-      engine: sqlite
-      database: ${SQLITE_DIRECTORY}/${SQLITE_DATABASE}
-    sql-include: test/sql/regress-sqlite.sql
-
-- title: Run the test collection
-  id: test-sqlite
-  tests:
-  - define: sqlite
-  - db: *connect
-  # The Regression Schema
-  - include: test/input/schema.yaml
-  # Examples from the Tutorial
-  - include: test/input/tutorial.yaml
-  # Standard Data Types, Functions, and Operations
-  - include: test/input/library.yaml
-  # Edge Cases of HTSQL-to-SQL Translation
-  - include: test/input/translation.yaml
-  # Formatting Output Data
-  - include: test/input/format.yaml
-

test/input/translation.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: Edge Cases of HTSQL-to-SQL Translation
-id: translation
-tests:
-
-# FIXME: update and refurbish!
-
-- title: Random collection of tests
-  tests:
-
-  # Simple (non-aggregate) filters.
-  - title: Simple filters
-    tests:
-    - uri: /school?code='ns'
-    - uri: /department?school.code='ns'
-    - uri: /department?school.code={'art','la'}
-    - uri: /program?school.code='ns'&code='uchem'
-    - uri: /course?credits=5
-    - uri: /department?school
-    # ENUM literal.
-    - uri: /semester?season='fall'
-    # Using the same term for a filter and a selector
-    - uri: /program{school.name,title}?school.code='art'
-
-  # Simple (non-aggregate) selectors.
-  - title: Simple selectors
-    tests:
-    - uri: /school{name}
-    - uri: /department{school.*,*}
-    - uri: /department{school.name+' - '+name}
-
-  # Plural links and aggregates.
-  - title: Aggregates
-    tests:
-    - uri: /exists(school)
-    - uri: /count(school)
-    - uri: /exists(school?exists(department))
-    - uri: /count(school?exists(department))
-    - uri: /{exists(school?!exists(department)),
-             count(school?!exists(department))}
-    - uri: /{count(course),min(course.credits),
-                           max(course.credits),
-                           avg(course.credits)}
-    - uri: /{count(school),count(department),count(course)}
-    - uri: /{count(department),count(department?exists(course))}
-    - uri: /department{code,count(course{credits=3})}
-    - uri: /department{code,count(course?credits=3)}
-    - uri: /school{code,count(department.course{credits=3})}
-    - uri: /school{code}?count(department.course{credits=3})=20
-    - uri: /department?exists(course.credits=5)
-    - uri: /department?every(course.credits=5)
-    - uri: /department{code,min(course.credits),max(course.credits)}
-    - uri: /department{code,avg(course.credits),
-                            sum(course.credits)/count(course.credits)}
-      skip: true
-    - uri: /department?exists(course)
-    - uri: /school?!exists(department)
-    - uri: /school{*,count(department)}
-    - uri: /school{*,count(department?exists(course))}
-    - uri: /school{*,count(department.exists(course))}
-    - uri: /school{code,count(department),count(program)}
-    - uri: /school{code,exists(department),exists(program)}
-      skip: true # broken until `reduce` is implemented
-    # Aggregates sharing the same spaces.
-    - uri: /department{sum(course.credits),count(course.credits),
-                       avg(course.credits)}?exists(course)
-    # Aggregates with non-native spaces.
-    # Triggers a bug in the Postgresql optimizer
-    # (see http://archives.postgresql.org/pgsql-bugs/2010-09/msg00265.php).
-    - uri: /department{code,school.code,
-                       count(school.program),school.count(program)}
-    - uri: /department{code,school.code,
-                       exists(school.program),school.exists(program)}
-    # Ensure that aggregates are not lost during the reduction process
-    - uri: /{count(school)&false(),count(school)|true()}
-    - uri: /{count(school)==null()}
-    # Reduction of aggregates to the scalar space.
-    - uri: /this(){count(school)}
-    - uri: /this(){count(school)}?false()
-    - uri: /this(){count(school)}?exists(school)
-    - uri: /this(){count(school)}?count(school)>1
-    # Unmasking and bundling aggregate units
-    - uri: /school{code,count(program)}?count(program)>3
-    # Merging terms with parallel ties
-    - uri: /school.program{school, code, degree,
-                           count(root(){(school?code='art').program.student})}
-                           ?school~'a'
-    - uri: /program.school{code, root().program{code, degree},
-                           count(root(){(program?degree='ba').school.department})}
-                           ?code~'a'
-
-  - title: Root, This, Direct and Fiber functions
-    tests:
-    # Cross joins.
-    - uri: /{count(school)*count(department),count(school.fiber(department))}
-    # Custom joins.
-    - uri: /{count(school.department),
-             count(school.fiber(department)?school=root().school.code),
-             count(school.fiber(department,code,school.code))}
-    - uri: /school{code,count(department)}?count(department)=max(fiber(school).count(department))
-    - uri: /school.program{school,code,count(student)}?count(student)=max(fiber(program,school).count(student))
-    # Lifting a unit to a dominating space.
-    - uri: /{count(school),this(){count(school)}?true(),this(){count(school)}?false()}
-    - uri: /school{code,name,this(){code}?name!~'art',
-                   root().school{code}?name!~'art'}
-    - uri: /school{name,count(department),this(){count(department)}?name!~'art'}
-    - uri: /school{name,exists(department),this(){exists(department)}?name!~'art'}
-
-  - title: Table Expressions
-    tests:
-    - uri: /(school?code='art').department
-
-  - title: Assignments
-    tests:
-    - uri: /school.let(c:=department.course.credits)
-                {code,min(c),max(c),sum(c),avg(c)}?exists(c)
-    - uri: /school.let(program:=(program?degree='bs')
-                                .let(student:=student?is_active))
-                {code,count(program),count(program.student)}?code='eng'
-    # FIXME?
-    - uri: /school{code,count(program.student),
-                   count((program.let(s:=student)?degree='bs').s),
-                   count((program?degree='bs').let(s:=student).s)}?code='eng'
-    - uri: /let(x:=2,y:=3,z:=x*y){x,y,z}
-    - uri: /let(x:=2,x:=x+x,x:=x*x){x}
-
-  - title: Projections
-    tests:
-    - uri: /quotient(program, degree)
-    - uri: /quotient(program, degree){*}
-    - uri: /quotient(program, degree){kernel()}
-    - uri: /quotient(program, degree)?false()
-    - uri: /quotient(program, degree){kernel()}?false()
-    - uri: /quotient(program, degree)?kernel()
-    - uri: /quotient(program, degree){kernel()}?kernel()
-    - uri: /quotient(program?false(), degree)
-    - uri: /quotient(program?degree, degree)
-    - uri: /quotient(program?false(), degree)?false()
-    - uri: /quotient(program?degree, degree)?kernel()
-    - uri: /quotient(program, degree){kernel(),count(complement())}
-      skip: true
-    - uri: /quotient(program, degree){kernel(),count(complement().student)}
-    - uri: /quotient(student, year(dob), gender)
-    - uri: /quotient(student, {year(dob), gender})
-    - uri: /quotient(student, {year(dob), gender}){kernel(),kernel(0),kernel(1)}
-    - uri: /quotient(student, {year(dob), gender}){kernel(),count(complement())}
-    - uri: /quotient(quotient(student, year(dob)).complement(), gender)
-                {kernel(), count(complement()), count(complement().is_active)}
-    - uri: /quotient(quotient(student, year(dob), gender), kernel(0))
-                {kernel(), count(complement()), count(complement().complement()),
-                 count(complement().complement().is_active)}
-    - uri: /school.quotient(program, degree)
-    - uri: /school.quotient(program, degree){*}
-    - uri: /school.quotient(program, degree){kernel()}
-    - uri: /school.quotient(program, degree)?false()
-    - uri: /school.quotient(program, degree){kernel()}?false()
-    - uri: /school.quotient(program, degree)?kernel()
-    - uri: /school.quotient(program, degree){kernel()}?kernel()
-    - uri: /school.quotient(program?false(), degree)
-    - uri: /school.quotient(program?degree, degree)
-    - uri: /school.quotient(program?false(), degree)?false()
-    - uri: /school.quotient(program?degree, degree)?kernel()
-    - uri: /school.quotient(program, degree){kernel(),count(complement())}
-    - uri: /school.quotient(program, degree){kernel(),count(complement().student)}
-
-    - uri: /school.program
-            .quotient(student, year(dob), gender)
-    - uri: /school.program
-            .quotient(student, {year(dob), gender})
-    - uri: /school.program
-            .quotient(student, {year(dob), gender}){kernel(),kernel(0),kernel(1)}
-    - uri: /school.program
-            .quotient(student, {year(dob), gender}){kernel(),count(complement())}
-    - uri: /school.program
-            .quotient(quotient(student, year(dob)).complement(), gender)
-                {kernel(), count(complement()), count(complement().is_active)}
-    - uri: /school.program
-            .quotient(quotient(student, year(dob), gender), kernel(0))
-                {kernel(), count(complement()), count(complement().complement()),
-                 count(complement().complement().is_active)}
-
-    - uri: /quotient(program,degree){kernel(),count(complement())}?count(complement())>5
-    - uri: /quotient(course,credits)?kernel()>3
-    - uri: /quotient(course,credits){kernel()-}
-    - uri: /(quotient((department?code='stdart').course,credits)?kernel()>3)
-                {*,count(complement())}
-    - uri: /quotient(school,count(program)){kernel(),count(complement())}
-    - uri: /school.quotient(program, degree)
-    - uri: /department.quotient(school.program, degree)
-    - uri: /department.quotient((school?code='art').program, degree)
-    - uri: /quotient(program,degree).complement()
-    - uri: /quotient(program.sort(count(student)),degree).complement()
-                {*, count(student)}
-    - uri: /quotient(program,degree){*,exists(complement()),count(complement())}
-    - uri: /school{code,count(program),count(quotient(program,degree))}
-    - uri: /school{code,count(program),count(program^degree)}
-    - uri: /(program^degree){*,count(^),count(^.student)}
-    - uri: /(student^{year(dob),gender}){*,count(^),count(^?is_active)}
-

test/input/tutorial.yaml

-#
-# Copyright (c) 2006-2011, Prometheus Research, LLC
-# Authors: Clark C. Evans <cce@clarkevans.com>,
-#          Kirill Simonov <xi@resolvent.net>
-#
-
-title: Examples from the Tutorial
-id: tutorial
-tests:
-
-- title: Getting Started
-  tests:
-  # Selecting Data
-  - uri: /school
-  - uri: /program{school, code, title}
-  - uri: /department{name-, school}
-  - uri: /course{department+, number, credits-, title}
-  - uri: /course{department+ :as 'Dept Code', number :as 'No.',
-                 credits-, title}
-  # Linking Data
-  - uri: /program{school.name, title}
-  - uri: /course{department.school.name, department.name, title}
-  - uri: /course{department{school.name, name}, title}
-  - uri: /department{*,school.*}
-  # Filtering Data
-  - uri: /department?school='eng'
-  - uri: /program?degree={'ba','bs'}
-  - uri: /program?school='bus'&degree!='bs'
-  - uri: /course{department, number, title}
-                ?credits<3&department.school='ns'
-  - uri: /(course?credits<3&department.school='ns')
-                {department, number, title}
-  # Formatters
-  - uri: /school/:json
-  # Putting it All Together
-  - uri: /course{department{code, name},number,title+}
-                ?department.school='bus'/:csv
-
-- title: Relating and Aggregating Data
-  tests:
-  # Basic Linking
-  - uri: /course{department.name, title}    # singular join
-  - uri: /department{name, course.credits}  # invalid plural join
-    expect: 400
-  - uri: /department{name, max(course.credits)}
-  - uri: /department{name, count(school)}   # invalid singular join
-    expect: 400
-  - uri: /max(course.credits)
-  # Aggregate Expressions
-  - uri: /school{name, count(program), count(department)}
-  - uri: /department{name, count(course?number>=400)}
-  - uri: /school{name, avg(department.count(course))}
-  - uri: /school{name, count(department?exists(course?credits>3))}
-  - uri: /department{name, avg((course?number>400).credits)}
-  - uri: /department{code, min(course.credits), max(course.credits),
-                           avg(course.credits)}
-  - uri: /department{name, avg(course.credits), count(course)}
-                ?every(course.credits=3)
-
-- title: Logical Expressions
-  tests:
-  # Comparison Operators
-  - uri: /course?title='Drawing'
-  - uri: /course?title~'lab'
-  - uri: /course?title!~'lab'
-  - uri: /course?title!='Organic Chemistry Laboratory I'
-  - uri: /course{department,number,title}?number=101
-  - uri: /course?department!={'arthis','stdart'}
-  - uri: /course?credits>3
-  - uri: /course?credits>=3
-  - uri: /department?code>'me'
-  # Boolean Expressions
-  - uri: /{true(), false(), null(), ''}
-  - uri: /department{code, name}?is_null(school)
-  - uri: /department{code, name}?!is_null(school)
-  - uri: /course?department='acc'&credits<3
-  - uri: /course?credits>4|credits<3
-  - uri: /course?(department='arthis'|department='stdart')&credits>3
-  - uri: /course?department='arthis'|department='stdart'&credits>3
-  - uri: /course?description
-  - uri: /course{department, number, description}?!description
-
-- title: Types and Functions
-  tests:
-  # Working with NULLs
-  - uri: /department?school=null()
-  - uri: /department?school==null()
-  - uri: /department?school!=='art'
-
-- title: Odds & Ends
-  tests:
-  - uri: /{1='1'}               # untyped literals
-  - uri: /{'Bursar''s Office'}  # single-quote escaping
-  - uri: /{'%25'}               # percent-encoding
-  - uri: /course.sort(credits)  # sort expression
-  - uri: /course.limit(5,20)    # limit/offset
-
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.