Line data Source code
1 : // Copyright (C) 2020 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.acceptance.testsuite.change; 16 : 17 : import com.google.auto.value.AutoValue; 18 : import com.google.common.collect.ImmutableMap; 19 : import com.google.gerrit.acceptance.testsuite.ThrowingFunction; 20 : import com.google.gerrit.acceptance.testsuite.change.TestRange.Position; 21 : import com.google.gerrit.common.Nullable; 22 : import com.google.gerrit.entities.Account; 23 : import com.google.gerrit.entities.Patch; 24 : import java.util.Map; 25 : import java.util.Optional; 26 : 27 : /** 28 : * Attributes of the robot comment. If not provided, arbitrary values will be used. This class is 29 : * very similar to {@link TestCommentCreation} to allow separation between robot and human comments. 30 : */ 31 : @AutoValue 32 3 : public abstract class TestRobotCommentCreation { 33 : 34 : public abstract Optional<String> message(); 35 : 36 : public abstract Optional<String> file(); 37 : 38 : public abstract Optional<Integer> line(); 39 : 40 : public abstract Optional<TestRange> range(); 41 : 42 : public abstract Optional<CommentSide> side(); 43 : 44 : public abstract Optional<String> parentUuid(); 45 : 46 : public abstract Optional<String> tag(); 47 : 48 : public abstract Optional<Account.Id> author(); 49 : 50 : public abstract Optional<String> robotId(); 51 : 52 : public abstract Optional<String> robotRunId(); 53 : 54 : public abstract Optional<String> url(); 55 : 56 : public abstract ImmutableMap<String, String> properties(); 57 : 58 : abstract ThrowingFunction<TestRobotCommentCreation, String> commentCreator(); 59 : 60 : public static Builder builder(ThrowingFunction<TestRobotCommentCreation, String> commentCreator) { 61 3 : return new AutoValue_TestRobotCommentCreation.Builder().commentCreator(commentCreator); 62 : } 63 : 64 : @AutoValue.Builder 65 3 : public abstract static class Builder { 66 : 67 : public Builder noMessage() { 68 1 : return message(""); 69 : } 70 : 71 : /** Message text of the comment. */ 72 : public abstract Builder message(String message); 73 : 74 : /** Indicates a patchset-level comment. */ 75 : public Builder onPatchsetLevel() { 76 1 : return file(Patch.PATCHSET_LEVEL); 77 : } 78 : 79 : /** Indicates a file comment. The comment will be on the specified file. */ 80 : public Builder onFileLevelOf(String filePath) { 81 1 : return file(filePath).line(null).range(null); 82 : } 83 : 84 : /** 85 : * Starts the fluent change to create a line comment. The line comment will be at the indicated 86 : * line. Lines start with 1. 87 : */ 88 : public FileBuilder<Builder> onLine(int line) { 89 1 : return new FileBuilder<>(file -> file(file).line(line).range(null)); 90 : } 91 : 92 : /** 93 : * Starts the fluent chain to create a range comment. The range begins at the specified line. 94 : * Lines start at 1. The start position (line, charOffset) is inclusive, the end position (line, 95 : * charOffset) is exclusive. 96 : */ 97 : public PositionBuilder<StartAwarePositionBuilder<Builder>> fromLine(int startLine) { 98 1 : return new PositionBuilder<>( 99 : startCharOffset -> { 100 1 : Position start = Position.builder().line(startLine).charOffset(startCharOffset).build(); 101 1 : TestRange.Builder testRangeBuilder = TestRange.builder().setStart(start); 102 1 : return new StartAwarePositionBuilder<>(testRangeBuilder, this::range, this::file); 103 : }); 104 : } 105 : 106 : /** File on which the comment should be added. */ 107 : abstract Builder file(String filePath); 108 : 109 : /** Line on which the comment should be added. */ 110 : abstract Builder line(@Nullable Integer line); 111 : 112 : /** Range on which the comment should be added. */ 113 : abstract Builder range(@Nullable TestRange range); 114 : 115 : /** 116 : * Indicates that the comment refers to a file, line, range, ... in the commit of the patchset. 117 : * 118 : * <p>On the UI, such comments are shown on the right side of a diff view when a diff against 119 : * base is selected. See {@link #onParentCommit()} for comments shown on the left side. 120 : */ 121 : public Builder onPatchsetCommit() { 122 1 : return side(CommentSide.PATCHSET_COMMIT); 123 : } 124 : 125 : /** 126 : * Indicates that the comment refers to a file, line, range, ... in the parent commit of the 127 : * patchset. 128 : * 129 : * <p>On the UI, such comments are shown on the left side of a diff view when a diff against 130 : * base is selected. See {@link #onPatchsetCommit()} for comments shown on the right side. 131 : * 132 : * <p>For merge commits, this indicates the first parent commit. 133 : */ 134 : public Builder onParentCommit() { 135 1 : return side(CommentSide.PARENT_COMMIT); 136 : } 137 : 138 : /** Like {@link #onParentCommit()} but for the second parent of a merge commit. */ 139 : public Builder onSecondParentCommit() { 140 1 : return side(CommentSide.SECOND_PARENT_COMMIT); 141 : } 142 : 143 : /** 144 : * Like {@link #onParentCommit()} but for the AutoMerge commit created from the parents of a 145 : * merge commit. 146 : */ 147 : public Builder onAutoMergeCommit() { 148 1 : return side(CommentSide.AUTO_MERGE_COMMIT); 149 : } 150 : 151 : abstract Builder side(CommentSide side); 152 : 153 : /** 154 : * UUID of another comment to which this comment is a reply. This comment must have similar 155 : * attributes (e.g. file, line, side) as the parent comment. The parent comment must be a 156 : * published comment. 157 : */ 158 : public abstract Builder parentUuid(String parentUuid); 159 : 160 : /** Tag to attach to the comment. */ 161 : public abstract Builder tag(String value); 162 : 163 : /** Author of the comment. Must be an existing user account. */ 164 : public abstract Builder author(Account.Id accountId); 165 : 166 : /** Id of the robot that created the comment. */ 167 : public abstract Builder robotId(String robotId); 168 : 169 : /** An ID of the run of the robot that created the comment. */ 170 : public abstract Builder robotRunId(String robotRunId); 171 : 172 : /** Url for more information for the robot comment. */ 173 : public abstract Builder url(String url); 174 : 175 : /** Robot specific properties as map that maps arbitrary keys to values. */ 176 : public abstract Builder properties(Map<String, String> properties); 177 : 178 : abstract ImmutableMap.Builder<String, String> propertiesBuilder(); 179 : 180 : public Builder addProperty(String key, String value) { 181 1 : propertiesBuilder().put(key, value); 182 1 : return this; 183 : } 184 : 185 : abstract Builder commentCreator( 186 : ThrowingFunction<TestRobotCommentCreation, String> commentCreator); 187 : 188 : abstract TestRobotCommentCreation autoBuild(); 189 : 190 : /** 191 : * Creates the robot comment. 192 : * 193 : * @return the UUID of the created robot comment 194 : */ 195 : public String create() { 196 3 : TestRobotCommentCreation commentCreation = autoBuild(); 197 3 : return commentCreation.commentCreator().applyAndThrowSilently(commentCreation); 198 : } 199 : } 200 : }