From 65659f924e1271514f623b215ebc6f1a122a502e Mon Sep 17 00:00:00 2001 From: Al Harris <91494052+alharris-at@users.noreply.github.com> Date: Tue, 20 Jun 2023 09:26:23 -0700 Subject: [PATCH 1/3] chore: add unit test coverage thresholds (#609) --- packages/amplify-codegen/package.json | 7 +++++++ packages/appsync-modelgen-plugin/package.json | 7 +++++++ packages/graphql-docs-generator/package.json | 7 +++++++ packages/graphql-types-generator/package.json | 7 +++++++ 4 files changed, 28 insertions(+) diff --git a/packages/amplify-codegen/package.json b/packages/amplify-codegen/package.json index 81cdf2116..028bec618 100644 --- a/packages/amplify-codegen/package.json +++ b/packages/amplify-codegen/package.json @@ -44,6 +44,13 @@ }, "jest": { "collectCoverage": true, + "coverageThreshold": { + "global": { + "branches": 56, + "functions": 68, + "lines": 73 + } + }, "testURL": "http://localhost", "testRegex": "((\\.|/)(test|spec))\\.(jsx?|tsx?)$", "moduleFileExtensions": [ diff --git a/packages/appsync-modelgen-plugin/package.json b/packages/appsync-modelgen-plugin/package.json index e5fdfdbab..c55675420 100644 --- a/packages/appsync-modelgen-plugin/package.json +++ b/packages/appsync-modelgen-plugin/package.json @@ -62,6 +62,13 @@ "collectCoverageFrom": [ "src/**/*.ts" ], + "coverageThreshold": { + "global": { + "branches": 80, + "functions": 80, + "lines": 80 + } + }, "testRegex": "(src/__tests__/.*.test.ts)$", "globals": { "ts-jest": { diff --git a/packages/graphql-docs-generator/package.json b/packages/graphql-docs-generator/package.json index d205ebcb7..a37592768 100644 --- a/packages/graphql-docs-generator/package.json +++ b/packages/graphql-docs-generator/package.json @@ -53,6 +53,13 @@ "collectCoverageFrom": [ "src/**/*.ts" ], + "coverageThreshold": { + "global": { + "branches": 64, + "functions": 71, + "lines": 80 + } + }, "moduleFileExtensions": [ "ts", "tsx", diff --git a/packages/graphql-types-generator/package.json b/packages/graphql-types-generator/package.json index fc73a3e17..6b4bf38ac 100644 --- a/packages/graphql-types-generator/package.json +++ b/packages/graphql-types-generator/package.json @@ -73,6 +73,13 @@ "/src/polyfills.js" ], "collectCoverage": true, + "coverageThreshold": { + "global": { + "branches": 79, + "functions": 80, + "lines": 80 + } + }, "testURL": "http://localhost", "setupFilesAfterEnv": [ "/test/test-utils/matchers.ts" From a33a960430e7d650ed09434f5f37f9ea338292c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Jun 2023 14:27:34 -0600 Subject: [PATCH 2/3] build(deps): bump semver from 7.5.1 to 7.5.2 (#611) Bumps [semver](https://github.com/npm/node-semver) from 7.5.1 to 7.5.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v7.5.1...v7.5.2) --- updated-dependencies: - dependency-name: semver dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index f5499eba9..084a4657e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7722,7 +7722,7 @@ create-require@^1.1.0: cross-fetch@2.2.2, cross-fetch@^2.2.6, cross-fetch@^3.1.5: version "2.2.6" - resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.6.tgz#2ef0bb39a24ac034787965c457368a28730e220a" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.6.tgz#2ef0bb39a24ac034787965c457368a28730e220a" integrity sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA== dependencies: node-fetch "^2.6.7" @@ -13172,9 +13172,9 @@ semver@7.5.0: lru-cache "^6.0.0" semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: - version "7.5.1" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec" - integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw== + version "7.5.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" + integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== dependencies: lru-cache "^6.0.0" @@ -14491,7 +14491,7 @@ whatwg-encoding@^1.0.5: whatwg-fetch@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== whatwg-mimetype@^2.3.0: From 852b7b2f45c2684c3645bbe6f52ff5432ec6536c Mon Sep 17 00:00:00 2001 From: Tyler Roach Date: Thu, 29 Jun 2023 12:45:44 -0400 Subject: [PATCH 3/3] feat: Add ModelIdentifier for all Java models (#612) --- packages/appsync-modelgen-plugin/package.json | 2 +- .../appsync-java-visitor.test.ts.snap | 715 +++++++++++++++++- .../visitors/appsync-java-visitor.test.ts | 37 + .../src/visitors/appsync-java-visitor.ts | 10 +- 4 files changed, 749 insertions(+), 15 deletions(-) diff --git a/packages/appsync-modelgen-plugin/package.json b/packages/appsync-modelgen-plugin/package.json index c55675420..7df7a2d30 100644 --- a/packages/appsync-modelgen-plugin/package.json +++ b/packages/appsync-modelgen-plugin/package.json @@ -42,7 +42,7 @@ "@graphql-codegen/testing": "^1.17.7", "@graphql-codegen/typescript": "^2.8.3", "graphql": "^15.5.0", - "java-ast": "^0.1.0", + "java-ast": "^0.3.0", "ts-json-schema-generator": "1.0.0" }, "peerDependencies": { diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap index 4ddb156aa..f4a9a0cf8 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/__snapshots__/appsync-java-visitor.test.ts.snap @@ -34,7 +34,9 @@ public final class Post implements Model { private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; private PostIdentifier postIdentifier; - public PostIdentifier resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public PostIdentifier resolveIdentifier() { if (postIdentifier == null) { this.postIdentifier = new PostIdentifier(id, title); } @@ -219,7 +221,9 @@ public final class Comment implements Model { private final @ModelField(targetType=\\"ID\\") String postCommentsId; private final @ModelField(targetType=\\"String\\") String postCommentsTitle; private CommentIdentifier commentIdentifier; - public CommentIdentifier resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public CommentIdentifier resolveIdentifier() { if (commentIdentifier == null) { this.commentIdentifier = new CommentIdentifier(id, content); } @@ -450,7 +454,9 @@ public final class Project implements Model { private final @ModelField(targetType=\\"ID\\") String projectTeamTeamId; private final @ModelField(targetType=\\"String\\") String projectTeamName; private ProjectIdentifier projectIdentifier; - public ProjectIdentifier resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public ProjectIdentifier resolveIdentifier() { if (projectIdentifier == null) { this.projectIdentifier = new ProjectIdentifier(projectId, name); } @@ -682,7 +688,9 @@ public final class Team implements Model { private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; private TeamIdentifier teamIdentifier; - public TeamIdentifier resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public TeamIdentifier resolveIdentifier() { if (teamIdentifier == null) { this.teamIdentifier = new TeamIdentifier(teamId, name); } @@ -887,7 +895,9 @@ public final class BlogOwnerWithCustomPKS implements Model { private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; private BlogOwnerWithCustomPKSIdentifier blogOwnerWithCustomPKSIdentifier; - public BlogOwnerWithCustomPKSIdentifier resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public BlogOwnerWithCustomPKSIdentifier resolveIdentifier() { if (blogOwnerWithCustomPKSIdentifier == null) { this.blogOwnerWithCustomPKSIdentifier = new BlogOwnerWithCustomPKSIdentifier(name, wea); } @@ -1104,7 +1114,9 @@ public final class Comment implements Model { private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; private CommentIdentifier commentIdentifier; - public CommentIdentifier resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public CommentIdentifier resolveIdentifier() { if (commentIdentifier == null) { this.commentIdentifier = new CommentIdentifier(title, content, likes); } @@ -1332,6 +1344,7 @@ exports[`AppSyncModelVisitor Custom primary key tests Should generate correct mo import com.amplifyframework.core.model.temporal.Temporal; import com.amplifyframework.core.model.annotations.BelongsTo; import com.amplifyframework.core.model.annotations.HasMany; +import com.amplifyframework.core.model.ModelIdentifier; import java.util.List; import java.util.UUID; @@ -1367,7 +1380,9 @@ public final class Post implements Model { private final @ModelField(targetType=\\"Comment\\") @HasMany(associatedWith = \\"post\\", type = Comment.class) List comments = null; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; - public String resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public String resolveIdentifier() { return postId; } @@ -1607,6 +1622,14 @@ public final class Post implements Model { } } + + public static class PostIdentifier extends ModelIdentifier { + private static final long serialVersionUID = 1L; + public PostIdentifier(String postId) { + super(postId); + } + } + } " `; @@ -1617,6 +1640,7 @@ exports[`AppSyncModelVisitor Custom primary key tests Should generate correct mo import com.amplifyframework.core.model.annotations.BelongsTo; import com.amplifyframework.core.model.annotations.HasMany; import com.amplifyframework.core.model.temporal.Temporal; +import com.amplifyframework.core.model.ModelIdentifier; import java.util.List; import java.util.UUID; @@ -1645,7 +1669,9 @@ public final class Blog implements Model { private final @ModelField(targetType=\\"Post\\") @HasMany(associatedWith = \\"blog\\", type = Post.class) List posts = null; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; - public String resolveIdentifier() { + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public String resolveIdentifier() { return id; } @@ -1818,6 +1844,14 @@ public final class Blog implements Model { } } + + public static class BlogIdentifier extends ModelIdentifier { + private static final long serialVersionUID = 1L; + public BlogIdentifier(String id) { + super(id); + } + } + } " `; @@ -4584,6 +4618,671 @@ public final class staticGroups implements Model { " `; +exports[`AppSyncModelVisitor ModelIdentifier for all model types tests Should generate ModelIdentifier factory with resolveIdentifier return type extending ModelIdentifier 1`] = ` +"package com.amplifyframework.datastore.generated.model; + +import com.amplifyframework.core.model.temporal.Temporal; +import com.amplifyframework.core.model.ModelIdentifier; + +import java.util.List; +import java.util.UUID; +import java.util.Objects; + +import androidx.core.util.ObjectsCompat; + +import com.amplifyframework.core.model.Model; +import com.amplifyframework.core.model.annotations.Index; +import com.amplifyframework.core.model.annotations.ModelConfig; +import com.amplifyframework.core.model.annotations.ModelField; +import com.amplifyframework.core.model.query.predicate.QueryField; + +import static com.amplifyframework.core.model.query.predicate.QueryField.field; + +/** This is an auto generated class representing the MyPost type in your schema. */ +@SuppressWarnings(\\"all\\") +@ModelConfig(pluralName = \\"MyPosts\\", type = Model.Type.USER, version = 1) +@Index(name = \\"undefined\\", fields = {\\"postId\\",\\"title\\",\\"createdAt\\",\\"rating\\"}) +public final class MyPost implements Model { + public static final QueryField POST_ID = field(\\"MyPost\\", \\"postId\\"); + public static final QueryField TITLE = field(\\"MyPost\\", \\"title\\"); + public static final QueryField CREATED_AT = field(\\"MyPost\\", \\"createdAt\\"); + public static final QueryField RATING = field(\\"MyPost\\", \\"rating\\"); + private final @ModelField(targetType=\\"ID\\", isRequired = true) String postId; + private final @ModelField(targetType=\\"String\\", isRequired = true) String title; + private final @ModelField(targetType=\\"AWSDateTime\\", isRequired = true) Temporal.DateTime createdAt; + private final @ModelField(targetType=\\"Float\\", isRequired = true) Double rating; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; + private MyPostIdentifier myPostIdentifier; + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public MyPostIdentifier resolveIdentifier() { + if (myPostIdentifier == null) { + this.myPostIdentifier = new MyPostIdentifier(postId, title, createdAt, rating); + } + return myPostIdentifier; + } + + public String getPostId() { + return postId; + } + + public String getTitle() { + return title; + } + + public Temporal.DateTime getCreatedAt() { + return createdAt; + } + + public Double getRating() { + return rating; + } + + public Temporal.DateTime getUpdatedAt() { + return updatedAt; + } + + private MyPost(String postId, String title, Temporal.DateTime createdAt, Double rating) { + this.postId = postId; + this.title = title; + this.createdAt = createdAt; + this.rating = rating; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if(obj == null || getClass() != obj.getClass()) { + return false; + } else { + MyPost myPost = (MyPost) obj; + return ObjectsCompat.equals(getPostId(), myPost.getPostId()) && + ObjectsCompat.equals(getTitle(), myPost.getTitle()) && + ObjectsCompat.equals(getCreatedAt(), myPost.getCreatedAt()) && + ObjectsCompat.equals(getRating(), myPost.getRating()) && + ObjectsCompat.equals(getUpdatedAt(), myPost.getUpdatedAt()); + } + } + + @Override + public int hashCode() { + return new StringBuilder() + .append(getPostId()) + .append(getTitle()) + .append(getCreatedAt()) + .append(getRating()) + .append(getUpdatedAt()) + .toString() + .hashCode(); + } + + @Override + public String toString() { + return new StringBuilder() + .append(\\"MyPost {\\") + .append(\\"postId=\\" + String.valueOf(getPostId()) + \\", \\") + .append(\\"title=\\" + String.valueOf(getTitle()) + \\", \\") + .append(\\"createdAt=\\" + String.valueOf(getCreatedAt()) + \\", \\") + .append(\\"rating=\\" + String.valueOf(getRating()) + \\", \\") + .append(\\"updatedAt=\\" + String.valueOf(getUpdatedAt())) + .append(\\"}\\") + .toString(); + } + + public static PostIdStep builder() { + return new Builder(); + } + + public CopyOfBuilder copyOfBuilder() { + return new CopyOfBuilder(postId, + title, + createdAt, + rating); + } + public interface PostIdStep { + TitleStep postId(String postId); + } + + + public interface TitleStep { + CreatedAtStep title(String title); + } + + + public interface CreatedAtStep { + RatingStep createdAt(Temporal.DateTime createdAt); + } + + + public interface RatingStep { + BuildStep rating(Double rating); + } + + + public interface BuildStep { + MyPost build(); + } + + + public static class Builder implements PostIdStep, TitleStep, CreatedAtStep, RatingStep, BuildStep { + private String postId; + private String title; + private Temporal.DateTime createdAt; + private Double rating; + @Override + public MyPost build() { + + return new MyPost( + postId, + title, + createdAt, + rating); + } + + @Override + public TitleStep postId(String postId) { + Objects.requireNonNull(postId); + this.postId = postId; + return this; + } + + @Override + public CreatedAtStep title(String title) { + Objects.requireNonNull(title); + this.title = title; + return this; + } + + @Override + public RatingStep createdAt(Temporal.DateTime createdAt) { + Objects.requireNonNull(createdAt); + this.createdAt = createdAt; + return this; + } + + @Override + public BuildStep rating(Double rating) { + Objects.requireNonNull(rating); + this.rating = rating; + return this; + } + } + + + public final class CopyOfBuilder extends Builder { + private CopyOfBuilder(String postId, String title, Temporal.DateTime createdAt, Double rating) { + super.postId(postId) + .title(title) + .createdAt(createdAt) + .rating(rating); + } + + @Override + public CopyOfBuilder postId(String postId) { + return (CopyOfBuilder) super.postId(postId); + } + + @Override + public CopyOfBuilder title(String title) { + return (CopyOfBuilder) super.title(title); + } + + @Override + public CopyOfBuilder createdAt(Temporal.DateTime createdAt) { + return (CopyOfBuilder) super.createdAt(createdAt); + } + + @Override + public CopyOfBuilder rating(Double rating) { + return (CopyOfBuilder) super.rating(rating); + } + } + + + public static class MyPostIdentifier extends ModelIdentifier { + private static final long serialVersionUID = 1L; + public MyPostIdentifier(String postId, String title, Temporal.DateTime createdAt, Double rating) { + super(postId, title, createdAt, rating); + } + } + +} +" +`; + +exports[`AppSyncModelVisitor ModelIdentifier for all model types tests Should generate ModelIdentifier factory with resolveIdentifier returning Java types matching graphql scalar conversion 1`] = ` +"package com.amplifyframework.datastore.generated.model; + +import com.amplifyframework.core.model.temporal.Temporal; +import com.amplifyframework.core.model.ModelIdentifier; + +import java.util.List; +import java.util.UUID; +import java.util.Objects; + +import androidx.core.util.ObjectsCompat; + +import com.amplifyframework.core.model.Model; +import com.amplifyframework.core.model.annotations.Index; +import com.amplifyframework.core.model.annotations.ModelConfig; +import com.amplifyframework.core.model.annotations.ModelField; +import com.amplifyframework.core.model.query.predicate.QueryField; + +import static com.amplifyframework.core.model.query.predicate.QueryField.field; + +/** This is an auto generated class representing the StringModel type in your schema. */ +@SuppressWarnings(\\"all\\") +@ModelConfig(pluralName = \\"StringModels\\", type = Model.Type.USER, version = 1) +@Index(name = \\"undefined\\", fields = {\\"customKey\\"}) +public final class StringModel implements Model { + public static final QueryField CUSTOM_KEY = field(\\"StringModel\\", \\"customKey\\"); + private final @ModelField(targetType=\\"String\\", isRequired = true) String customKey; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public String resolveIdentifier() { + return customKey; + } + + public String getCustomKey() { + return customKey; + } + + public Temporal.DateTime getCreatedAt() { + return createdAt; + } + + public Temporal.DateTime getUpdatedAt() { + return updatedAt; + } + + private StringModel(String customKey) { + this.customKey = customKey; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if(obj == null || getClass() != obj.getClass()) { + return false; + } else { + StringModel stringModel = (StringModel) obj; + return ObjectsCompat.equals(getCustomKey(), stringModel.getCustomKey()) && + ObjectsCompat.equals(getCreatedAt(), stringModel.getCreatedAt()) && + ObjectsCompat.equals(getUpdatedAt(), stringModel.getUpdatedAt()); + } + } + + @Override + public int hashCode() { + return new StringBuilder() + .append(getCustomKey()) + .append(getCreatedAt()) + .append(getUpdatedAt()) + .toString() + .hashCode(); + } + + @Override + public String toString() { + return new StringBuilder() + .append(\\"StringModel {\\") + .append(\\"customKey=\\" + String.valueOf(getCustomKey()) + \\", \\") + .append(\\"createdAt=\\" + String.valueOf(getCreatedAt()) + \\", \\") + .append(\\"updatedAt=\\" + String.valueOf(getUpdatedAt())) + .append(\\"}\\") + .toString(); + } + + public static CustomKeyStep builder() { + return new Builder(); + } + + public CopyOfBuilder copyOfBuilder() { + return new CopyOfBuilder(customKey); + } + public interface CustomKeyStep { + BuildStep customKey(String customKey); + } + + + public interface BuildStep { + StringModel build(); + } + + + public static class Builder implements CustomKeyStep, BuildStep { + private String customKey; + @Override + public StringModel build() { + + return new StringModel( + customKey); + } + + @Override + public BuildStep customKey(String customKey) { + Objects.requireNonNull(customKey); + this.customKey = customKey; + return this; + } + } + + + public final class CopyOfBuilder extends Builder { + private CopyOfBuilder(String customKey) { + super.customKey(customKey); + } + + @Override + public CopyOfBuilder customKey(String customKey) { + return (CopyOfBuilder) super.customKey(customKey); + } + } + + + public static class StringModelIdentifier extends ModelIdentifier { + private static final long serialVersionUID = 1L; + public StringModelIdentifier(String customKey) { + super(customKey); + } + } + +} +" +`; + +exports[`AppSyncModelVisitor ModelIdentifier for all model types tests Should generate ModelIdentifier factory with resolveIdentifier returning Java types matching graphql scalar conversion 2`] = ` +"package com.amplifyframework.datastore.generated.model; + +import com.amplifyframework.core.model.temporal.Temporal; +import com.amplifyframework.core.model.ModelIdentifier; + +import java.util.List; +import java.util.UUID; +import java.util.Objects; + +import androidx.core.util.ObjectsCompat; + +import com.amplifyframework.core.model.Model; +import com.amplifyframework.core.model.annotations.Index; +import com.amplifyframework.core.model.annotations.ModelConfig; +import com.amplifyframework.core.model.annotations.ModelField; +import com.amplifyframework.core.model.query.predicate.QueryField; + +import static com.amplifyframework.core.model.query.predicate.QueryField.field; + +/** This is an auto generated class representing the IdModel type in your schema. */ +@SuppressWarnings(\\"all\\") +@ModelConfig(pluralName = \\"IdModels\\", type = Model.Type.USER, version = 1) +@Index(name = \\"undefined\\", fields = {\\"customKey\\"}) +public final class IdModel implements Model { + public static final QueryField CUSTOM_KEY = field(\\"IdModel\\", \\"customKey\\"); + private final @ModelField(targetType=\\"ID\\", isRequired = true) String customKey; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public String resolveIdentifier() { + return customKey; + } + + public String getCustomKey() { + return customKey; + } + + public Temporal.DateTime getCreatedAt() { + return createdAt; + } + + public Temporal.DateTime getUpdatedAt() { + return updatedAt; + } + + private IdModel(String customKey) { + this.customKey = customKey; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if(obj == null || getClass() != obj.getClass()) { + return false; + } else { + IdModel idModel = (IdModel) obj; + return ObjectsCompat.equals(getCustomKey(), idModel.getCustomKey()) && + ObjectsCompat.equals(getCreatedAt(), idModel.getCreatedAt()) && + ObjectsCompat.equals(getUpdatedAt(), idModel.getUpdatedAt()); + } + } + + @Override + public int hashCode() { + return new StringBuilder() + .append(getCustomKey()) + .append(getCreatedAt()) + .append(getUpdatedAt()) + .toString() + .hashCode(); + } + + @Override + public String toString() { + return new StringBuilder() + .append(\\"IdModel {\\") + .append(\\"customKey=\\" + String.valueOf(getCustomKey()) + \\", \\") + .append(\\"createdAt=\\" + String.valueOf(getCreatedAt()) + \\", \\") + .append(\\"updatedAt=\\" + String.valueOf(getUpdatedAt())) + .append(\\"}\\") + .toString(); + } + + public static CustomKeyStep builder() { + return new Builder(); + } + + public CopyOfBuilder copyOfBuilder() { + return new CopyOfBuilder(customKey); + } + public interface CustomKeyStep { + BuildStep customKey(String customKey); + } + + + public interface BuildStep { + IdModel build(); + } + + + public static class Builder implements CustomKeyStep, BuildStep { + private String customKey; + @Override + public IdModel build() { + + return new IdModel( + customKey); + } + + @Override + public BuildStep customKey(String customKey) { + Objects.requireNonNull(customKey); + this.customKey = customKey; + return this; + } + } + + + public final class CopyOfBuilder extends Builder { + private CopyOfBuilder(String customKey) { + super.customKey(customKey); + } + + @Override + public CopyOfBuilder customKey(String customKey) { + return (CopyOfBuilder) super.customKey(customKey); + } + } + + + public static class IdModelIdentifier extends ModelIdentifier { + private static final long serialVersionUID = 1L; + public IdModelIdentifier(String customKey) { + super(customKey); + } + } + +} +" +`; + +exports[`AppSyncModelVisitor ModelIdentifier for all model types tests Should generate ModelIdentifier factory with resolveIdentifier returning Java types matching graphql scalar conversion 3`] = ` +"package com.amplifyframework.datastore.generated.model; + +import com.amplifyframework.core.model.temporal.Temporal; +import com.amplifyframework.core.model.ModelIdentifier; + +import java.util.List; +import java.util.UUID; +import java.util.Objects; + +import androidx.core.util.ObjectsCompat; + +import com.amplifyframework.core.model.Model; +import com.amplifyframework.core.model.annotations.Index; +import com.amplifyframework.core.model.annotations.ModelConfig; +import com.amplifyframework.core.model.annotations.ModelField; +import com.amplifyframework.core.model.query.predicate.QueryField; + +import static com.amplifyframework.core.model.query.predicate.QueryField.field; + +/** This is an auto generated class representing the IntModel type in your schema. */ +@SuppressWarnings(\\"all\\") +@ModelConfig(pluralName = \\"IntModels\\", type = Model.Type.USER, version = 1) +@Index(name = \\"undefined\\", fields = {\\"customKey\\"}) +public final class IntModel implements Model { + public static final QueryField CUSTOM_KEY = field(\\"IntModel\\", \\"customKey\\"); + private final @ModelField(targetType=\\"Int\\", isRequired = true) Integer customKey; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime createdAt; + private @ModelField(targetType=\\"AWSDateTime\\", isReadOnly = true) Temporal.DateTime updatedAt; + /** @deprecated This API is internal to Amplify and should not be used. */ + @Deprecated + public Integer resolveIdentifier() { + return customKey; + } + + public Integer getCustomKey() { + return customKey; + } + + public Temporal.DateTime getCreatedAt() { + return createdAt; + } + + public Temporal.DateTime getUpdatedAt() { + return updatedAt; + } + + private IntModel(Integer customKey) { + this.customKey = customKey; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if(obj == null || getClass() != obj.getClass()) { + return false; + } else { + IntModel intModel = (IntModel) obj; + return ObjectsCompat.equals(getCustomKey(), intModel.getCustomKey()) && + ObjectsCompat.equals(getCreatedAt(), intModel.getCreatedAt()) && + ObjectsCompat.equals(getUpdatedAt(), intModel.getUpdatedAt()); + } + } + + @Override + public int hashCode() { + return new StringBuilder() + .append(getCustomKey()) + .append(getCreatedAt()) + .append(getUpdatedAt()) + .toString() + .hashCode(); + } + + @Override + public String toString() { + return new StringBuilder() + .append(\\"IntModel {\\") + .append(\\"customKey=\\" + String.valueOf(getCustomKey()) + \\", \\") + .append(\\"createdAt=\\" + String.valueOf(getCreatedAt()) + \\", \\") + .append(\\"updatedAt=\\" + String.valueOf(getUpdatedAt())) + .append(\\"}\\") + .toString(); + } + + public static CustomKeyStep builder() { + return new Builder(); + } + + public CopyOfBuilder copyOfBuilder() { + return new CopyOfBuilder(customKey); + } + public interface CustomKeyStep { + BuildStep customKey(Integer customKey); + } + + + public interface BuildStep { + IntModel build(); + } + + + public static class Builder implements CustomKeyStep, BuildStep { + private Integer customKey; + @Override + public IntModel build() { + + return new IntModel( + customKey); + } + + @Override + public BuildStep customKey(Integer customKey) { + Objects.requireNonNull(customKey); + this.customKey = customKey; + return this; + } + } + + + public final class CopyOfBuilder extends Builder { + private CopyOfBuilder(Integer customKey) { + super.customKey(customKey); + } + + @Override + public CopyOfBuilder customKey(Integer customKey) { + return (CopyOfBuilder) super.customKey(customKey); + } + } + + + public static class IntModelIdentifier extends ModelIdentifier { + private static final long serialVersionUID = 1L; + public IntModelIdentifier(Integer customKey) { + super(customKey); + } + } + +} +" +`; + exports[`AppSyncModelVisitor Non model type should generate class for model types with non model fields 1`] = ` "package com.amplifyframework.datastore.generated.model; diff --git a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts index c3315abc5..c9959a159 100644 --- a/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts +++ b/packages/appsync-modelgen-plugin/src/__tests__/visitors/appsync-java-visitor.test.ts @@ -702,4 +702,41 @@ describe('AppSyncModelVisitor', () => { expect(generatedCodeComment).toMatchSnapshot(); }); }); + + describe('ModelIdentifier for all model types tests', () => { + it('Should generate ModelIdentifier factory with resolveIdentifier return type extending ModelIdentifier', () => { + const schema = /* GraphQL */ ` + type MyPost @model { + postId: ID! @primaryKey(sortKeyFields: ["title", "createdAt", "rating"]) + title: String! + createdAt: AWSDateTime! + rating: Float! + } + `; + const generatedCodeMyPost = getVisitorPipelinedTransformer(schema, `MyPost`, { respectPrimaryKeyAttributesOnConnectionField: true }).generate(); + expect(generatedCodeMyPost).toMatchSnapshot(); + }); + it('Should generate ModelIdentifier factory with resolveIdentifier returning Java types matching graphql scalar conversion', () => { + const schema = /* GraphQL */ ` + type StringModel @model { + customKey: String! @primaryKey + } + + type IdModel @model { + customKey: ID! @primaryKey + } + + type IntModel @model { + customKey: Int! @primaryKey + } + `; + const generatedCodeStringModel= getVisitorPipelinedTransformer(schema, 'StringModel', { respectPrimaryKeyAttributesOnConnectionField: true }).generate(); + const generatedCodeIdModel = getVisitorPipelinedTransformer(schema, 'IdModel', { respectPrimaryKeyAttributesOnConnectionField: true }).generate(); + const generatedCodeIntModel = getVisitorPipelinedTransformer(schema, 'IntModel', { respectPrimaryKeyAttributesOnConnectionField: true }).generate(); + + expect(generatedCodeStringModel).toMatchSnapshot(); + expect(generatedCodeIdModel).toMatchSnapshot(); + expect(generatedCodeIntModel).toMatchSnapshot(); + }); + }); }); diff --git a/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts b/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts index fd6202b1e..d9d5541ee 100644 --- a/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts +++ b/packages/appsync-modelgen-plugin/src/visitors/appsync-java-visitor.ts @@ -205,7 +205,7 @@ export class AppSyncModelJavaVisitor< isIdAsModelPrimaryKey = primaryKeyType !== CodeGenPrimaryKeyType.CustomId; } - if (isCompositeKey && this.isCustomPKEnabled()) { + if (this.isCustomPKEnabled() && isCompositeKey) { // Generate primary key class for composite key this.generateIdentifierClassField(model, classDeclarationBlock); } @@ -221,10 +221,8 @@ export class AppSyncModelJavaVisitor< this.generateCopyOfBuilderClass(model, classDeclarationBlock, isIdAsModelPrimaryKey); if (this.isCustomPKEnabled()) { - if (isCompositeKey) { - // Model primary Key class for composite primary key - this.generateModelIdentifierClass(model, classDeclarationBlock); - } + // Generate ModelIdentifier factory for all Model types + this.generateModelIdentifierClass(model, classDeclarationBlock); // resolveIdentifier this.generateResolveIdentifier(model, classDeclarationBlock, isCompositeKey); @@ -654,7 +652,7 @@ export class AppSyncModelJavaVisitor< `return ${modelIdentifierClassFieldName};` ].join('\n') : `return ${this.getFieldName(primaryKeyField)};`; - declarationsBlock.addClassMethod('resolveIdentifier', returnType, body, undefined, undefined, 'public'); + declarationsBlock.addClassMethod('resolveIdentifier', returnType, body, [], [], 'public', {}, ["Deprecated"], [], "@deprecated This API is internal to Amplify and should not be used."); } /**