artemis
artemis copied to clipboard
Fragment on interface - generates not existing case
In case of using
... on Node {
...NodeFrag
}
it generates case statement that refers to not existent class
case r'Node':
return (this as Custom$Query$Node$Node).toJson();
Just put this code in test file
import 'package:artemis/generator/data.dart';
import 'package:test/test.dart';
import '../../helpers.dart';
void main() {
group('On interfaces', () {
test(
'On interfaces',
() async => testGenerator(
query: query,
schema: graphQLSchema,
libraryDefinition: libraryDefinition,
generatedFile: generatedFile,
),
);
});
}
const query = r'''
query custom($id: ID!) {
nodeById(id: $id) {
... on Node {
...NodeFrag
}
... on User {
...UserFrag
}
... on ChatMessage {
message
user {
...UserFrag
}
}
}
}
fragment UserFrag on User {
id
username
}
fragment NodeFrag on Node {
id
}
''';
// https://graphql-code-generator.com/#live-demo
final String graphQLSchema = r'''
scalar String
scalar ID
schema {
query: Query
}
type Query {
nodeById(id: ID!): Node
}
interface Node {
id: ID!
}
type User implements Node {
id: ID!
username: String!
}
type ChatMessage implements Node {
id: ID!
message: String!
user: User!
}
''';
final LibraryDefinition libraryDefinition =
LibraryDefinition(basename: r'query.graphql', queries: [
QueryDefinition(
queryName: r'custom',
queryType: r'Custom$Query',
classes: [
ClassDefinition(
name: r'Custom$Query$Node$User',
extension: r'Custom$Query$Node',
mixins: [r'UserFragMixin'],
factoryPossibilities: {},
typeNameField: r'__typename',
isInput: false),
ClassDefinition(
name: r'Custom$Query$Node$ChatMessage$User',
extension: r'Custom$Query$Node$ChatMessage',
mixins: [r'UserFragMixin'],
factoryPossibilities: {},
typeNameField: r'__typename',
isInput: false),
ClassDefinition(
name: r'Custom$Query$Node$ChatMessage',
properties: [
ClassProperty(
type: r'String',
name: r'message',
isNonNull: true,
isResolveType: false),
ClassProperty(
type: r'Custom$Query$Node$ChatMessage$User',
name: r'user',
isNonNull: true,
isResolveType: false)
],
extension: r'Custom$Query$Node',
factoryPossibilities: {},
typeNameField: r'__typename',
isInput: false),
ClassDefinition(
name: r'Custom$Query$Node',
properties: [
ClassProperty(
type: r'String',
name: r'typeName',
annotations: [
r'override',
r'''JsonKey(name: '__typename')'''
],
isNonNull: false,
isResolveType: true)
],
factoryPossibilities: {
r'Node': r'Custom$Query$Node$Node',
r'User': r'Custom$Query$Node$User',
r'ChatMessage': r'Custom$Query$Node$ChatMessage'
},
typeNameField: r'__typename',
isInput: false),
ClassDefinition(
name: r'Custom$Query',
properties: [
ClassProperty(
type: r'Custom$Query$Node',
name: r'nodeById',
isNonNull: false,
isResolveType: false)
],
factoryPossibilities: {},
typeNameField: r'__typename',
isInput: false),
FragmentClassDefinition(name: r'UserFragMixin', properties: [
ClassProperty(
type: r'String',
name: r'id',
isNonNull: true,
isResolveType: false),
ClassProperty(
type: r'String',
name: r'username',
isNonNull: true,
isResolveType: false)
]),
FragmentClassDefinition(name: r'NodeFragMixin', properties: [
ClassProperty(
type: r'String',
name: r'id',
isNonNull: true,
isResolveType: false)
])
],
inputs: [QueryInput(type: r'String', name: r'id', isNonNull: true)],
generateHelpers: false,
suffix: r'Query')
]);
const generatedFile = r'''// GENERATED CODE - DO NOT MODIFY BY HAND
import 'package:meta/meta.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:equatable/equatable.dart';
import 'package:gql/ast.dart';
part 'query.graphql.g.dart';
mixin UserFragMixin {
String id;
String username;
}
mixin NodeFragMixin {
String id;
}
@JsonSerializable(explicitToJson: true)
class Custom$Query$Node$User extends Custom$Query$Node
with EquatableMixin, UserFragMixin {
Custom$Query$Node$User();
factory Custom$Query$Node$User.fromJson(Map<String, dynamic> json) =>
_$Custom$Query$Node$UserFromJson(json);
@override
List<Object> get props => [id, username];
Map<String, dynamic> toJson() => _$Custom$Query$Node$UserToJson(this);
}
@JsonSerializable(explicitToJson: true)
class Custom$Query$Node$ChatMessage$User extends Custom$Query$Node$ChatMessage
with EquatableMixin, UserFragMixin {
Custom$Query$Node$ChatMessage$User();
factory Custom$Query$Node$ChatMessage$User.fromJson(
Map<String, dynamic> json) =>
_$Custom$Query$Node$ChatMessage$UserFromJson(json);
@override
List<Object> get props => [id, username];
Map<String, dynamic> toJson() =>
_$Custom$Query$Node$ChatMessage$UserToJson(this);
}
@JsonSerializable(explicitToJson: true)
class Custom$Query$Node$ChatMessage extends Custom$Query$Node
with EquatableMixin {
Custom$Query$Node$ChatMessage();
factory Custom$Query$Node$ChatMessage.fromJson(Map<String, dynamic> json) =>
_$Custom$Query$Node$ChatMessageFromJson(json);
String message;
Custom$Query$Node$ChatMessage$User user;
@override
List<Object> get props => [message, user];
Map<String, dynamic> toJson() => _$Custom$Query$Node$ChatMessageToJson(this);
}
@JsonSerializable(explicitToJson: true)
class Custom$Query$Node with EquatableMixin {
Custom$Query$Node();
factory Custom$Query$Node.fromJson(Map<String, dynamic> json) {
switch (json['__typename'].toString()) {
case r'Node':
return Custom$Query$Node$Node.fromJson(json);
case r'User':
return Custom$Query$Node$User.fromJson(json);
case r'ChatMessage':
return Custom$Query$Node$ChatMessage.fromJson(json);
default:
}
return _$Custom$Query$NodeFromJson(json);
}
@override
@JsonKey(name: '__typename')
String typeName;
@override
List<Object> get props => [typeName];
Map<String, dynamic> toJson() {
switch (typeName) {
case r'Node':
return (this as Custom$Query$Node$Node).toJson();
case r'User':
return (this as Custom$Query$Node$User).toJson();
case r'ChatMessage':
return (this as Custom$Query$Node$ChatMessage).toJson();
default:
}
return _$Custom$Query$NodeToJson(this);
}
}
@JsonSerializable(explicitToJson: true)
class Custom$Query with EquatableMixin {
Custom$Query();
factory Custom$Query.fromJson(Map<String, dynamic> json) =>
_$Custom$QueryFromJson(json);
Custom$Query$Node nodeById;
@override
List<Object> get props => [nodeById];
Map<String, dynamic> toJson() => _$Custom$QueryToJson(this);
}
''';
I am having this same issue.
Although for me, the fragment fails to ~~build~~ parse whether I have another fragment inside of the interface or not.
Both of these produce the same output:
fragment TextMessage on Text {
id
body
audit {
createdBy {
entity {
... on User {
...UserGql
}
}
}
}
}
fragment TextMessage on Text {
id
body
audit {
createdBy {
entity {
... on User {
id
firstName
lastName
}
}
}
}
}
This is the very last bug that is keeping us from using Artemis for our project. All the other issues have been resolved in these last few beta builds. Great work guys!
Hi. Try to change your query in the next way and try again.
fragment TextMessage on Text {
id
body
audit {
createdBy {
entity {
...UserGql
}
}
}
}
Hi. Try to change your query in the next way and try again.
fragment TextMessage on Text { id body audit { createdBy { entity { ...UserGql } } } }
@vasilich6107 Hello.
When I try to build with the above code, I correctly get this error:
Exception: Field id was not found in GraphQL type Actor.
Make sure your query is correct and your schema is updated.
In the schema there are multiple possible interfaces in that entity, so although this error is pretty vague, it makes sense for the build to error out.
Hmmm, I faced the same issue(
@vasilich6107 Were you able to find a work-around for this by any chance?
@m-Skolnick could you attach your schema and full query?
@vasilich6107 I wish I could, but I can't share our schema. However, I would be happy to test and report back the results if that would be helpful.
Share only the core part and rename the fields))) So I can experiment with solution
I'm not sure if this will be helpful, but here it is. It's just an interface that an object conforms to.
interface hasDisplayName {
"""A string used to display the player"""
displayName: String!
}
type User implements hasDisplayName {
"""A string used to display the displayName"""
displayName: String!
firstName: String!
lastName:String!
}
Full Schema and full query please
Is there any progress or workaround?