Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #356 from comigor/missing-fragment
Browse files Browse the repository at this point in the history
Add throwable errors for missing root object and used query fragments
  • Loading branch information
comigor authored Oct 14, 2021
2 parents 03beece + d7d177a commit b886094
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CHANGELOG

## 7.2.2-beta
- Add throwable errors for missing root object and used query fragments

## 7.2.1-beta
- Update package to use official Dart lint following [this guide](https://github.com/dart-lang/lints#migrating-from-packagepedantic)

Expand Down
7 changes: 5 additions & 2 deletions lib/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,11 @@ Iterable<QueryDefinition> generateDefinitions(
.value ??
suffix;

final TypeDefinitionNode parentType =
objectVisitor.getByName(rootTypeName)!;
final parentType = objectVisitor.getByName(rootTypeName);

if (parentType == null) {
throw MissingRootTypeException(rootTypeName);
}

final name = QueryName.fromPath(
path: createPathName([
Expand Down
33 changes: 33 additions & 0 deletions lib/generator/errors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,36 @@ configured on `build.yaml`!
Please configure it, following the README on `scalar_mapping`.
''';
}

/// Thrown when Artemis can't find the default (or configured) root object type
/// on schema.
class MissingRootTypeException implements Exception {
/// Thrown when Artemis can't find the default (or configured) root object
/// type on schema.
const MissingRootTypeException(this.rootTypeName);

/// The missing root type name.
final String rootTypeName;

@override
String toString() => '''Can't find the "$rootTypeName" root type.
Make sure your schema file contains it.
''';
}

/// Thrown when Artemis can't find the requested fragment on schema.
class MissingFragmentException implements Exception {
/// Thrown when Artemis can't find the requested fragment on schema.
const MissingFragmentException(this.fragmentName, this.className);

/// The missing fragment name.
final String fragmentName;

/// The class name in which the fragment is used.
final String className;

@override
String toString() => '''Can't find the "$fragmentName" in "$className".
Make sure files inside `fragments_glob` or the query file contains it.
''';
}
4 changes: 4 additions & 0 deletions lib/generator/print_helpers.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:artemis/generator/data/data.dart';
import 'package:artemis/generator/data/enum_value_definition.dart';
import 'package:artemis/generator/errors.dart';
import 'package:code_builder/code_builder.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:dart_style/dart_style.dart';
Expand Down Expand Up @@ -118,6 +119,9 @@ Spec classDefinitionToSpec(
return fragments
.firstWhere((f) {
return f.name == i;
}, orElse: () {
throw MissingFragmentException(
i.namePrintable, definition.name.namePrintable);
})
.properties
.map((p) => p.name.namePrintable);
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: artemis
version: 7.2.1-beta
version: 7.2.2-beta

description: Build dart types from GraphQL schemas and queries (using Introspection Query).
homepage: https://github.com/comigor/artemis
Expand Down
42 changes: 42 additions & 0 deletions test/query_generator/errors/fragment_not_found_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:artemis/builder.dart';
import 'package:artemis/generator/errors.dart';
import 'package:build/build.dart';
import 'package:build_test/build_test.dart';
import 'package:test/test.dart';

void main() {
group('On errors', () {
test('When there\'s a missing fragment being used', () async {
final anotherBuilder = graphQLQueryBuilder(BuilderOptions({
'generate_helpers': false,
'schema_mapping': [
{
'schema': 'api.schema.graphql',
'queries_glob': 'lib/queries/some_query.graphql',
'output': 'lib/output/some_query.graphql.dart',
},
],
}));

expect(
() => testBuilder(
anotherBuilder,
{
'a|api.schema.graphql': '''
type Query {
a: String!
}
''',
'a|lib/queries/some_query.graphql':
'query { ...nonExistentFragment }',
},
onLog: print,
),
throwsA(predicate((e) =>
e is MissingFragmentException &&
e.fragmentName == 'NonExistentFragmentMixin' &&
e.className == r'SomeQuery$Query')),
);
});
});
}
36 changes: 36 additions & 0 deletions test/query_generator/errors/root_type_not_found_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'package:artemis/builder.dart';
import 'package:artemis/generator/errors.dart';
import 'package:build/build.dart';
import 'package:build_test/build_test.dart';
import 'package:test/test.dart';

void main() {
group('On errors', () {
test('When there\'s no root type on schema', () async {
final anotherBuilder = graphQLQueryBuilder(BuilderOptions({
'generate_helpers': false,
'schema_mapping': [
{
'schema': 'lib/api.schema.graphql',
'queries_glob': 'lib/**.query.graphql',
'output': 'lib/some_query.graphql.dart',
},
],
}));

anotherBuilder.onBuild = expectAsync1((_) {}, count: 0);

expect(
() => testBuilder(
anotherBuilder,
{
'a|lib/api.schema.graphql': '',
'a|lib/some.query.graphql': 'query { a }',
},
onLog: print,
),
throwsA(predicate((e) => e is MissingRootTypeException)),
);
});
});
}

0 comments on commit b886094

Please sign in to comment.