argument+directive
This commit is contained in:
parent
5c2649d2d9
commit
9e942d8221
6 changed files with 131 additions and 5 deletions
2
.analysis-options
Normal file
2
.analysis-options
Normal file
|
@ -0,0 +1,2 @@
|
|||
analyzer:
|
||||
strong-mode: true
|
|
@ -9,6 +9,8 @@ class ArgumentContext extends Node {
|
|||
|
||||
ArgumentContext(this.NAME, this.COLON, this.valueOrVariable);
|
||||
|
||||
String get name => NAME.text;
|
||||
|
||||
@override
|
||||
SourceSpan get span =>
|
||||
new SourceSpan(NAME.span?.start, valueOrVariable.end, toSource());
|
||||
|
|
|
@ -7,7 +7,6 @@ import 'token_type.dart';
|
|||
|
||||
class Parser {
|
||||
Token _current;
|
||||
final List<SyntaxError> _errors = [];
|
||||
int _index = -1;
|
||||
|
||||
final List<Token> tokens;
|
||||
|
@ -16,8 +15,6 @@ class Parser {
|
|||
|
||||
Token get current => _current;
|
||||
|
||||
List<SyntaxError> get errors => new List<SyntaxError>.unmodifiable(_errors);
|
||||
|
||||
bool next(TokenType type) {
|
||||
if (peek()?.type == type) {
|
||||
_current = tokens[++_index];
|
||||
|
@ -84,7 +81,7 @@ class Parser {
|
|||
ARROBA, NAME, null, LPAREN, current, arg, null);
|
||||
} else
|
||||
throw new SyntaxError.fromSourceLocation(
|
||||
'Expected \'(\'', arg.valueOrVariable.span.end);
|
||||
'Expected \')\'', arg.valueOrVariable.span.end);
|
||||
} else
|
||||
throw new SyntaxError.fromSourceLocation(
|
||||
'Expected argument in directive.', LPAREN.span.end);
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import 'package:test/test.dart';
|
||||
import 'argument_test.dart' as argument;
|
||||
import 'directive_test.dart' as directive;
|
||||
import 'value_test.dart' as value;
|
||||
import 'variable_test.dart' as variable;
|
||||
|
||||
main() {
|
||||
group('argument', argument.main);
|
||||
group('directive', directive.main);
|
||||
group('value', value.main);
|
||||
}
|
||||
group('variable', variable.main);
|
||||
}
|
||||
|
|
43
test/argument_test.dart
Normal file
43
test/argument_test.dart
Normal file
|
@ -0,0 +1,43 @@
|
|||
import 'package:graphql_parser/graphql_parser.dart';
|
||||
import 'package:matcher/matcher.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'common.dart';
|
||||
|
||||
main() {
|
||||
test('argument', () {
|
||||
expect('foo: 2', isArgument('foo', 2));
|
||||
expect(r'foo: $bar', isArgument('foo', 'bar'));
|
||||
});
|
||||
|
||||
test('exception', () {
|
||||
expect(() => parseArgument('foo'), throwsSyntaxError);
|
||||
expect(() => parseArgument('foo:'), throwsSyntaxError);
|
||||
});
|
||||
}
|
||||
|
||||
ArgumentContext parseArgument(String text) => parse(text).parseArgument();
|
||||
|
||||
Matcher isArgument(String name, value) => new _IsArgument(name, value);
|
||||
|
||||
class _IsArgument extends Matcher {
|
||||
final String name;
|
||||
final value;
|
||||
|
||||
_IsArgument(this.name, this.value);
|
||||
|
||||
@override
|
||||
Description describe(Description description) {
|
||||
return description.add('is an argument named "$name" with value $value');
|
||||
}
|
||||
|
||||
@override
|
||||
bool matches(item, Map matchState) {
|
||||
var arg = item is ArgumentContext ? item : parseArgument(item);
|
||||
if (arg == null) return false;
|
||||
return equals(name).matches(arg.name, matchState) &&
|
||||
equals(value).matches(
|
||||
arg.valueOrVariable.value?.value ??
|
||||
arg.valueOrVariable.variable?.name,
|
||||
matchState);
|
||||
}
|
||||
}
|
76
test/directive_test.dart
Normal file
76
test/directive_test.dart
Normal file
|
@ -0,0 +1,76 @@
|
|||
import 'package:graphql_parser/graphql_parser.dart';
|
||||
import 'package:matcher/matcher.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'argument_test.dart';
|
||||
import 'common.dart';
|
||||
|
||||
main() {
|
||||
test('name only', () {
|
||||
expect('@foo', isDirective('foo'));
|
||||
});
|
||||
|
||||
test('with value or variable', () {
|
||||
expect('@foo: 2', isDirective('foo', valueOrVariable: equals(2)));
|
||||
expect(r'@foo: $bar', isDirective('foo', valueOrVariable: equals('bar')));
|
||||
});
|
||||
|
||||
test('with argument', () {
|
||||
expect('@foo (bar: 2)', isDirective('foo', argument: isArgument('bar', 2)));
|
||||
expect(r'@foo (bar: $baz)',
|
||||
isDirective('foo', argument: isArgument('bar', r'baz')));
|
||||
});
|
||||
|
||||
test('exceptions', () {
|
||||
expect(() => parseDirective('@'), throwsSyntaxError);
|
||||
expect(() => parseDirective('@foo:'), throwsSyntaxError);
|
||||
expect(() => parseDirective('@foo ('), throwsSyntaxError);
|
||||
expect(() => parseDirective('@foo (bar: 2'), throwsSyntaxError);
|
||||
expect(() => parseDirective('@foo ()'), throwsSyntaxError);
|
||||
});
|
||||
}
|
||||
|
||||
DirectiveContext parseDirective(String text) => parse(text).parseDirective();
|
||||
|
||||
Matcher isDirective(String name, {Matcher valueOrVariable, Matcher argument}) =>
|
||||
new _IsDirective(name,
|
||||
valueOrVariable: valueOrVariable, argument: argument);
|
||||
|
||||
class _IsDirective extends Matcher {
|
||||
final String name;
|
||||
final Matcher valueOrVariable, argument;
|
||||
|
||||
_IsDirective(this.name, {this.valueOrVariable, this.argument});
|
||||
|
||||
@override
|
||||
Description describe(Description description) {
|
||||
var desc = description.add('is a directive with name "$name"');
|
||||
|
||||
if (valueOrVariable != null) {
|
||||
return valueOrVariable.describe(desc.add(' and '));
|
||||
} else if (argument != null) {
|
||||
return argument.describe(desc.add(' and '));
|
||||
} else
|
||||
return desc;
|
||||
}
|
||||
|
||||
@override
|
||||
bool matches(String item, Map matchState) {
|
||||
var directive = parseDirective(item);
|
||||
if (directive == null) return false;
|
||||
if (valueOrVariable != null) {
|
||||
if (directive.valueOrVariable == null)
|
||||
return false;
|
||||
else
|
||||
return valueOrVariable.matches(
|
||||
directive.valueOrVariable.value?.value ??
|
||||
directive.valueOrVariable.variable?.name,
|
||||
matchState);
|
||||
} else if (argument != null) {
|
||||
if (directive.argument == null)
|
||||
return false;
|
||||
else
|
||||
return argument.matches(directive.argument, matchState);
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue