Use enforceHasSpan on all parse results in tests

This commit is contained in:
Simon Binder 2019-10-27 11:51:09 +01:00
parent 591e1b2bff
commit a304d13927
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
13 changed files with 59 additions and 52 deletions

View File

@ -52,6 +52,10 @@ abstract class AstNode with HasMetaMixin {
/// all nodes.
Token last;
/// Whether this ast node is synthetic, meaning that it doesn't appear in the
/// actual source.
bool synthetic;
/// The first index in the source that belongs to this node. Not set for all
/// nodes.
int get firstPosition => first.span.start.offset;

View File

@ -674,7 +674,7 @@ mixin CrudParser on ParserBase {
baseWindowName: baseWindowName,
partitionBy: partitionBy,
orderBy: orderBy,
frameSpec: spec ?? FrameSpec(),
frameSpec: spec ?? (FrameSpec()..synthetic = true),
)..setSpan(leftParen, _previous);
}

View File

@ -266,9 +266,8 @@ mixin ExpressionParser on ParserBase {
final selectStmt = _fullSelect(); // returns null if there's no select
if (selectStmt != null) {
final stmt = select(noCompound: true) as SelectStatement;
_consume(TokenType.rightParen, 'Expected a closing bracket');
return SubQuery(select: stmt)..setSpan(left, _previous);
return SubQuery(select: selectStmt)..setSpan(left, _previous);
} else {
final expr = expression();
_consume(TokenType.rightParen, 'Expected a closing bracket');
@ -382,7 +381,8 @@ mixin ExpressionParser on ParserBase {
_consume(TokenType.leftParen, 'Expected opening parenthesis for tuple');
final expressions = <Expression>[];
final subQuery = _fullSelect();
// if desired, attempt to parse select statement
final subQuery = orSubQuery ? _fullSelect() : null;
if (subQuery == null) {
// no sub query found. read expressions that form the tuple.
// tuples can be empty `()`, so only start parsing values when it's not

View File

@ -1,6 +1,5 @@
import 'package:sqlparser/sqlparser.dart';
import 'package:sqlparser/src/ast/ast.dart';
import 'package:sqlparser/src/utils/ast_equality.dart';
import 'package:test/test.dart';
import '../common_data.dart';
@ -118,11 +117,8 @@ void main() {
});
test('parses MAPPED BY constraints when in moor mode', () {
const stmt = 'CREATE TABLE a (b NOT NULL MAPPED BY `Mapper()` PRIMARY KEY)';
final parsed = SqlEngine(useMoorExtensions: true).parse(stmt).rootNode;
enforceEqual(
parsed,
testStatement(
'CREATE TABLE a (b NOT NULL MAPPED BY `Mapper()` PRIMARY KEY)',
CreateTableStatement(tableName: 'a', columns: [
ColumnDefinition(
columnName: 'b',
@ -134,15 +130,13 @@ void main() {
],
),
]),
moorMode: true,
);
});
test('parses JSON KEY constraints in moor mode', () {
const stmt = 'CREATE TABLE a (b INTEGER JSON KEY "my_json_key")';
final parsed = SqlEngine(useMoorExtensions: true).parse(stmt).rootNode;
enforceEqual(
parsed,
testStatement(
'CREATE TABLE a (b INTEGER JSON KEY "my_json_key")',
CreateTableStatement(
tableName: 'a',
columns: [
@ -158,6 +152,7 @@ void main() {
),
],
),
moorMode: true,
);
});
}

View File

@ -146,8 +146,8 @@ void main() {
final tokens = scanner.scanTokens();
final parser = Parser(tokens);
final expression = parser.expression();
enforceHasSpan(expression);
enforceHasSpan(expression);
enforceEqual(expression, expected);
});
});

View File

@ -1,5 +1,4 @@
import 'package:sqlparser/sqlparser.dart';
import 'package:sqlparser/src/utils/ast_equality.dart';
import 'package:test/test.dart';
import 'utils.dart';
@ -19,12 +18,8 @@ all: SELECT /* COUNT(*), */ * FROM tbl WHERE $predicate;
void main() {
test('parses moor files', () {
final parsed = SqlEngine(useMoorExtensions: true).parseMoorFile(content);
final file = parsed.rootNode;
enforceHasSpan(file);
enforceEqual(
file,
testMoorFile(
content,
MoorFile([
ImportStatement('other.dart'),
ImportStatement('another.moor'),

View File

@ -4,16 +4,15 @@ import 'package:sqlparser/src/reader/tokenizer/scanner.dart';
import 'package:sqlparser/src/utils/ast_equality.dart';
import 'package:test/test.dart';
import 'utils.dart';
void main() {
test('can parse multiple statements', () {
final sql = 'a: UPDATE tbl SET a = b; b: SELECT * FROM tbl;';
final tokens = Scanner(sql).scanTokens();
final moorFile = Parser(tokens).moorFile();
final statements = moorFile.statements;
enforceEqual(
statements[0],
testMoorFile(
sql,
MoorFile([
DeclaredStatement(
'a',
UpdateStatement(
@ -26,9 +25,6 @@ void main() {
],
),
),
);
enforceEqual(
statements[1],
DeclaredStatement(
'b',
SelectStatement(
@ -36,6 +32,7 @@ void main() {
from: [TableReference('tbl', null)],
),
),
]),
);
});

View File

@ -63,6 +63,8 @@ void main() {
final tokens = scanner.scanTokens();
final parser = Parser(tokens);
final expression = parser.expression();
enforceHasSpan(expression);
enforceEqual(expression, expected);
});
});

View File

@ -6,6 +6,7 @@ import 'package:sqlparser/src/utils/ast_equality.dart';
import '../utils.dart';
void _enforceFrom(SelectStatement stmt, List<Queryable> expected) {
enforceHasSpan(stmt);
expect(stmt.from.length, expected.length);
for (var i = 0; i < stmt.from.length; i++) {

View File

@ -11,6 +11,7 @@ void main() {
.parse("SELECT * FROM test GROUP BY country HAVING country LIKE '%G%'")
.rootNode as SelectStatement;
enforceHasSpan(stmt);
return enforceEqual(
stmt.groupBy,
GroupBy(

View File

@ -12,6 +12,7 @@ void main() {
.parse('SELECT * FROM test LIMIT 5 * 3')
.rootNode as SelectStatement;
enforceHasSpan(select);
enforceEqual(
select.limit,
Limit(
@ -29,6 +30,7 @@ void main() {
.parse('SELECT * FROM test LIMIT 10 OFFSET 2')
.rootNode as SelectStatement;
enforceHasSpan(select);
enforceEqual(
select.limit,
Limit(
@ -46,6 +48,7 @@ void main() {
.parse('SELECT * FROM test LIMIT 10, 2')
.rootNode as SelectStatement;
enforceHasSpan(select);
enforceEqual(
select.limit,
Limit(

View File

@ -11,6 +11,7 @@ void main() {
.parse('SELECT * FROM tbl ORDER BY -a, b DESC')
.rootNode as SelectStatement;
enforceHasSpan(parsed);
enforceEqual(
parsed.orderBy,
OrderBy(

View File

@ -18,6 +18,14 @@ IdentifierToken identifier(String content) {
return IdentifierToken(false, fakeSpan(content));
}
void testMoorFile(String moorFile, MoorFile expected) {
final parsed =
SqlEngine(useMoorExtensions: true).parseMoorFile(moorFile).rootNode;
enforceHasSpan(parsed);
enforceEqual(parsed, expected);
}
void testStatement(String sql, AstNode expected, {bool moorMode = false}) {
final parsed = SqlEngine(useMoorExtensions: moorMode).parse(sql).rootNode;
enforceHasSpan(parsed);
@ -38,9 +46,9 @@ void testAll(Map<String, AstNode> testCases) {
/// The parser should make sure [AstNode.hasSpan] is true on relevant nodes.
void enforceHasSpan(AstNode node) {
final problematic = [node]
.followedBy(node.allDescendants)
.firstWhere((node) => !node.hasSpan, orElse: () => null);
final problematic = [node].followedBy(node.allDescendants).firstWhere(
(node) => !node.hasSpan && !node.synthetic,
orElse: () => null);
if (problematic != null) {
throw ArgumentError('Node $problematic did not have a span');