diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkBuildWrapper.java b/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkBuildWrapper.java index 6913e16..df7ca96 100644 --- a/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkBuildWrapper.java +++ b/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkBuildWrapper.java @@ -10,7 +10,8 @@ import hudson.tasks.BuildWrapperDescriptor; import org.apache.commons.lang.StringUtils; import org.jenkinsci.plugins.typetalk.api.Typetalk; -import org.jenkinsci.plugins.typetalk.api.TypetalkMessage; +import org.jenkinsci.plugins.typetalk.support.Emoji; +import org.jenkinsci.plugins.typetalk.support.TypetalkMessage; import org.kohsuke.stapler.DataBoundConstructor; import java.io.IOException; @@ -41,8 +42,8 @@ public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener l String message; if (StringUtils.isBlank(notifyStartMessage)) { - TypetalkMessage typetalkMessage = new TypetalkMessage(TypetalkMessage.Emoji.LOUDSPEAKER, "Build start"); - message = typetalkMessage.messageWithBuildInfo(build); + TypetalkMessage typetalkMessage = new TypetalkMessage(Emoji.LOUDSPEAKER, "Build start"); + message = typetalkMessage.buildMessageWithBuild(build); } else{ message = build.getEnvironment(listener).expand(notifyStartMessage); } @@ -59,8 +60,8 @@ public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOEx String message; if (StringUtils.isBlank(notifyEndMessage)) { - TypetalkMessage typetalkMessage = new TypetalkMessage(TypetalkMessage.Emoji.MEGA, "Build end"); - message = typetalkMessage.messageWithBuildInfo(build); + TypetalkMessage typetalkMessage = new TypetalkMessage(Emoji.MEGA, "Build end"); + message = typetalkMessage.buildMessageWithBuild(build); } else { message = build.getEnvironment(listener).expand(notifyEndMessage); } diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkNotifier.java b/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkNotifier.java index 369b86a..d237596 100644 --- a/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkNotifier.java +++ b/src/main/java/org/jenkinsci/plugins/typetalk/TypetalkNotifier.java @@ -13,7 +13,8 @@ import hudson.util.Secret; import net.sf.json.JSONObject; import org.jenkinsci.plugins.typetalk.api.Typetalk; -import org.jenkinsci.plugins.typetalk.api.TypetalkMessage; +import org.jenkinsci.plugins.typetalk.support.ResultSupport; +import org.jenkinsci.plugins.typetalk.support.TypetalkMessage; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; @@ -47,8 +48,8 @@ public boolean perform(AbstractBuild build, Launcher launcher, BuildListen listener.getLogger().println("Notifying build result to Typetalk..."); - TypetalkMessage typetalkMessage = TypetalkMessage.convertFromResult(build); - String message = typetalkMessage.messageWithBuildInfo(build); + TypetalkMessage typetalkMessage = new ResultSupport().convertBuildToMessage(build); + String message = typetalkMessage.buildMessageWithBuild(build); Long topicId = Long.valueOf(topicNumber); Typetalk.createFromName(name).postMessage(topicId, message); diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/api/Typetalk.java b/src/main/java/org/jenkinsci/plugins/typetalk/api/Typetalk.java index 09fb344..7d0952d 100644 --- a/src/main/java/org/jenkinsci/plugins/typetalk/api/Typetalk.java +++ b/src/main/java/org/jenkinsci/plugins/typetalk/api/Typetalk.java @@ -4,20 +4,12 @@ import com.google.api.client.auth.oauth2.ClientCredentialsTokenRequest; import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.auth.oauth2.TokenResponse; -import com.google.api.client.http.BasicAuthentication; -import com.google.api.client.http.GenericUrl; -import com.google.api.client.http.HttpContent; -import com.google.api.client.http.HttpRequest; -import com.google.api.client.http.HttpRequestFactory; -import com.google.api.client.http.HttpRequestInitializer; -import com.google.api.client.http.HttpResponse; -import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.*; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.http.json.JsonHttpContent; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.JsonObjectParser; import com.google.api.client.json.jackson.JacksonFactory; -import hudson.model.AbstractBuild; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; import org.jenkinsci.plugins.typetalk.TypetalkNotifier; diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/api/TypetalkMessage.java b/src/main/java/org/jenkinsci/plugins/typetalk/api/TypetalkMessage.java deleted file mode 100644 index 798ff13..0000000 --- a/src/main/java/org/jenkinsci/plugins/typetalk/api/TypetalkMessage.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.jenkinsci.plugins.typetalk.api; - -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.Result; -import jenkins.model.Jenkins; -import org.apache.commons.lang.StringUtils; - -public class TypetalkMessage { - - public enum Emoji { - LOUDSPEAKER(":loudspeaker:"), - MEGA(":mega:"), - ASTONISHED(":astonished:"), - RAGE(":rage:"), - CRY(":cry:"), - SMILEY(":smiley:"), - MASK(":mask:"), - BOOK(":book:"), - PAGE_FACING_UP(":page_facing_up:"); - - private String symbol; - - public String getSymbol() { - return symbol; - } - - Emoji(String symbol) { - this.symbol = symbol; - } - } - - private final Emoji emoji; - private final String message; - - public Emoji getEmoji() { - return emoji; - } - - public String getMessage() { - return message; - } - - public TypetalkMessage(Emoji emoji, String message) { - this.emoji = emoji; - this.message = message; - } - - public static TypetalkMessage convertFromResult(AbstractBuild build) { - if (build.getResult().equals(Result.ABORTED)) { - return new TypetalkMessage(Emoji.ASTONISHED, "Build aborted"); - } else if (build.getResult().equals(Result.NOT_BUILT)) { - return new TypetalkMessage(Emoji.ASTONISHED, "Not built"); - } else if (build.getResult().equals(Result.FAILURE)) { - return new TypetalkMessage(Emoji.RAGE, "Build failure"); - } else if (build.getResult().equals(Result.UNSTABLE)) { - return new TypetalkMessage(Emoji.CRY, "Build unstable"); - } else if (build.getResult().equals(Result.SUCCESS)) { - if (recoverSuccess(build)) { - return new TypetalkMessage(Emoji.SMILEY, "Build recovery"); - } else { - return new TypetalkMessage(Emoji.SMILEY, "Build success"); - } - } - - throw new IllegalArgumentException("Unknown build result."); - } - - private static boolean recoverSuccess(AbstractBuild build) { - if (build.getPreviousBuild() == null) { - return false; - } else { - return build.getResult().equals(Result.SUCCESS) - && build.getPreviousBuild().getResult().isWorseThan(Result.SUCCESS); - } - } - - public String messageWithBuildInfo(AbstractBuild build) { - final String rootUrl = Jenkins.getInstance().getRootUrl(); - if (StringUtils.isEmpty(rootUrl)) { - throw new IllegalStateException("Root URL isn't configured yet. Cannot compute absolute URL."); - } - - final StringBuilder builder = new StringBuilder(); - builder.append(emoji.symbol); - builder.append(" "); - builder.append(message); - builder.append(" [ "); - builder.append(build.getProject().getDisplayName()); - builder.append(" ]"); - builder.append("\n"); - builder.append(rootUrl); - builder.append(build.getUrl()); - - return builder.toString(); - } - - public String messageWithProjectInfo(AbstractProject project) { - final String rootUrl = Jenkins.getInstance().getRootUrl(); - if (StringUtils.isEmpty(rootUrl)) { - throw new IllegalStateException("Root URL isn't configured yet. Cannot compute absolute URL."); - } - - final StringBuilder builder = new StringBuilder(); - builder.append(emoji.symbol); - builder.append(" "); - builder.append(message); - builder.append("\n"); - builder.append(rootUrl); - if (project != null) { - builder.append(project.getUrl()); - } - - return builder.toString(); - } - -} diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/support/Emoji.java b/src/main/java/org/jenkinsci/plugins/typetalk/support/Emoji.java new file mode 100644 index 0000000..5e53493 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/typetalk/support/Emoji.java @@ -0,0 +1,23 @@ +package org.jenkinsci.plugins.typetalk.support; + +public enum Emoji { + LOUDSPEAKER(":loudspeaker:"), + MEGA(":mega:"), + ASTONISHED(":astonished:"), + RAGE(":rage:"), + CRY(":cry:"), + SMILEY(":smiley:"), + MASK(":mask:"), + BOOK(":book:"), + PAGE_FACING_UP(":page_facing_up:"); + + private String symbol; + + public String getSymbol() { + return symbol; + } + + Emoji(String symbol) { + this.symbol = symbol; + } +} diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/support/ResultSupport.java b/src/main/java/org/jenkinsci/plugins/typetalk/support/ResultSupport.java new file mode 100644 index 0000000..62e34ce --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/typetalk/support/ResultSupport.java @@ -0,0 +1,59 @@ +package org.jenkinsci.plugins.typetalk.support; + +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.Result; + +public class ResultSupport { + + public TypetalkMessage convertBuildToMessage(AbstractBuild build) { + if (build.getResult().equals(Result.ABORTED)) { + return new TypetalkMessage(Emoji.ASTONISHED, "Build aborted"); + } else if (build.getResult().equals(Result.NOT_BUILT)) { + return new TypetalkMessage(Emoji.ASTONISHED, "Not built"); + } else if (build.getResult().equals(Result.FAILURE)) { + return new TypetalkMessage(Emoji.RAGE, "Build failure"); + } else if (build.getResult().equals(Result.UNSTABLE)) { + return new TypetalkMessage(Emoji.CRY, "Build unstable"); + } else if (build.getResult().equals(Result.SUCCESS)) { + if (recoverSuccess(build)) { + return new TypetalkMessage(Emoji.SMILEY, "Build recovery"); + } else { + return new TypetalkMessage(Emoji.SMILEY, "Build success"); + } + } + + throw new IllegalArgumentException("Unknown build result."); + } + + public boolean recoverSuccess(AbstractBuild build) { + if (build.getPreviousBuild() == null) { + return false; + } else { + return build.getResult().equals(Result.SUCCESS) + && build.getPreviousBuild().getResult().isWorseThan(Result.SUCCESS); + } + } + + public Emoji convertProjectToEmoji(AbstractProject project) { + switch (project.getIconColor()) { + case RED: + case RED_ANIME: + return Emoji.RAGE; + case YELLOW: + case YELLOW_ANIME: + return Emoji.CRY; + case BLUE: + case BLUE_ANIME: + return Emoji.SMILEY; + case DISABLED: + case DISABLED_ANIME: + case NOTBUILT: + case NOTBUILT_ANIME: + return Emoji.MASK; + default: + return Emoji.ASTONISHED; + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/support/TypetalkMessage.java b/src/main/java/org/jenkinsci/plugins/typetalk/support/TypetalkMessage.java new file mode 100644 index 0000000..a065e41 --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/typetalk/support/TypetalkMessage.java @@ -0,0 +1,65 @@ +package org.jenkinsci.plugins.typetalk.support; + +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; + +public class TypetalkMessage { + + private final Emoji emoji; + private final String message; + + public Emoji getEmoji() { + return emoji; + } + + public String getMessage() { + return message; + } + + public TypetalkMessage(Emoji emoji, String message) { + this.emoji = emoji; + this.message = message; + } + + public String buildMessageWithBuild(AbstractBuild build) { + final String rootUrl = Jenkins.getInstance().getRootUrl(); + if (StringUtils.isEmpty(rootUrl)) { + throw new IllegalStateException("Root URL isn't configured yet. Cannot compute absolute URL."); + } + + final StringBuilder builder = new StringBuilder(); + builder.append(emoji.getSymbol()); + builder.append(" "); + builder.append(message); + builder.append(" [ "); + builder.append(build.getProject().getDisplayName()); + builder.append(" ]"); + builder.append("\n"); + builder.append(rootUrl); + builder.append(build.getUrl()); + + return builder.toString(); + } + + public String buildMessageWithProject(AbstractProject project) { + final String rootUrl = Jenkins.getInstance().getRootUrl(); + if (StringUtils.isEmpty(rootUrl)) { + throw new IllegalStateException("Root URL isn't configured yet. Cannot compute absolute URL."); + } + + final StringBuilder builder = new StringBuilder(); + builder.append(emoji.getSymbol()); + builder.append(" "); + builder.append(message); + builder.append("\n"); + builder.append(rootUrl); + if (project != null) { + builder.append(project.getUrl()); + } + + return builder.toString(); + } + +} diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/ResponseParameter.java b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/ResponseParameter.java index 101ca72..346e56c 100644 --- a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/ResponseParameter.java +++ b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/ResponseParameter.java @@ -1,7 +1,7 @@ package org.jenkinsci.plugins.typetalk.webhookaction; import hudson.model.AbstractProject; -import org.jenkinsci.plugins.typetalk.api.TypetalkMessage; +import org.jenkinsci.plugins.typetalk.support.Emoji; import java.util.List; @@ -23,13 +23,13 @@ public String getMessage() { return message; } - private TypetalkMessage.Emoji emoji; + private Emoji emoji; - public TypetalkMessage.Emoji getEmoji() { - return emoji != null ? emoji : TypetalkMessage.Emoji.SMILEY; + public Emoji getEmoji() { + return emoji != null ? emoji : Emoji.SMILEY; } - public void setEmoji(TypetalkMessage.Emoji emoji) { + public void setEmoji(Emoji emoji) { this.emoji = emoji; } diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/WebhookExecutor.java b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/WebhookExecutor.java index 7a20e38..c79ff8c 100644 --- a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/WebhookExecutor.java +++ b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/WebhookExecutor.java @@ -1,7 +1,8 @@ package org.jenkinsci.plugins.typetalk.webhookaction; import net.sf.json.JSONObject; -import org.jenkinsci.plugins.typetalk.api.TypetalkMessage; +import org.jenkinsci.plugins.typetalk.support.Emoji; +import org.jenkinsci.plugins.typetalk.support.TypetalkMessage; import org.kohsuke.stapler.StaplerResponse; import javax.servlet.http.HttpServletResponse; @@ -30,7 +31,7 @@ protected void output(ResponseParameter parameter) { } protected void outputError(ResponseParameter parameter) { - parameter.setEmoji(TypetalkMessage.Emoji.CRY); + parameter.setEmoji(Emoji.CRY); outputInternal(Level.WARNING, parameter); } @@ -50,7 +51,7 @@ private String buildResponseMessage(ResponseParameter parameter) { JSONObject jsonObject = new JSONObject(); TypetalkMessage typetalkMessage = new TypetalkMessage(parameter.getEmoji(), parameter.getMessage()); - jsonObject.element("message", typetalkMessage.messageWithProjectInfo(parameter.getProject())); + jsonObject.element("message", typetalkMessage.buildMessageWithProject(parameter.getProject())); jsonObject.element("replyTo", req.getPostId()); return jsonObject.toString(); diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/HelpExecutor.java b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/HelpExecutor.java index b4716db..69d892b 100644 --- a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/HelpExecutor.java +++ b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/HelpExecutor.java @@ -1,9 +1,12 @@ package org.jenkinsci.plugins.typetalk.webhookaction.executorimpl; -import hudson.model.*; +import hudson.model.AbstractProject; +import hudson.model.ParameterDefinition; +import hudson.model.ParametersDefinitionProperty; +import hudson.model.TopLevelItem; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; -import org.jenkinsci.plugins.typetalk.api.TypetalkMessage; +import org.jenkinsci.plugins.typetalk.support.Emoji; import org.jenkinsci.plugins.typetalk.webhookaction.ResponseParameter; import org.jenkinsci.plugins.typetalk.webhookaction.WebhookExecutor; import org.jenkinsci.plugins.typetalk.webhookaction.WebhookRequest; @@ -38,7 +41,7 @@ public void execute() { } responseParameter.setDescription("Command [ help ] is executed"); - responseParameter.setEmoji(TypetalkMessage.Emoji.BOOK); + responseParameter.setEmoji(Emoji.BOOK); output(responseParameter); } @@ -82,7 +85,7 @@ private ResponseParameter getBuildResponseParameter() { messages.add("```"); messages.add(botUser + " build ()"); messages.add("```"); - messages.add(TypetalkMessage.Emoji.BOOK.getSymbol() + " Sample"); + messages.add(Emoji.BOOK.getSymbol() + " Sample"); messages.add("```"); messages.add(botUser + " build helloWorldProject | build without parameters"); messages.add(botUser + " build helloWorldProject 1.0.0 | build with only single parameter"); @@ -119,7 +122,7 @@ private ResponseParameter getProjectBuildResponseParameter(String p) { // parameter ( if defined ) if (property != null) { - messages.add(TypetalkMessage.Emoji.BOOK.getSymbol() + " Parameters"); + messages.add(Emoji.BOOK.getSymbol() + " Parameters"); messages.add("```"); int maxParameterLength = 0; @@ -147,7 +150,7 @@ private ResponseParameter getListResponseParameter() { messages.add("```"); messages.add(botUser + " list ()"); messages.add("```"); - messages.add(TypetalkMessage.Emoji.BOOK.getSymbol() + " Sample"); + messages.add(Emoji.BOOK.getSymbol() + " Sample"); messages.add("```"); messages.add(botUser + " list | list all projects "); messages.add(botUser + " list helloWorld | list projects with simple filter"); diff --git a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/ListExecutor.java b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/ListExecutor.java index 50a8bba..de57ce8 100644 --- a/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/ListExecutor.java +++ b/src/main/java/org/jenkinsci/plugins/typetalk/webhookaction/executorimpl/ListExecutor.java @@ -4,7 +4,8 @@ import hudson.model.TopLevelItem; import jenkins.model.Jenkins; import org.apache.commons.lang.StringUtils; -import org.jenkinsci.plugins.typetalk.api.TypetalkMessage; +import org.jenkinsci.plugins.typetalk.support.Emoji; +import org.jenkinsci.plugins.typetalk.support.ResultSupport; import org.jenkinsci.plugins.typetalk.webhookaction.ResponseParameter; import org.jenkinsci.plugins.typetalk.webhookaction.WebhookExecutor; import org.jenkinsci.plugins.typetalk.webhookaction.WebhookRequest; @@ -30,7 +31,7 @@ public ListExecutor(WebhookRequest req, StaplerResponse rsp, String pattern) { @Override public void execute() { ArrayList messages = new ArrayList<>(); - TypetalkMessage.Emoji emoji; + Emoji CommandEmoji; for (TopLevelItem item : Jenkins.getInstance().getItems()) { if (!(item instanceof AbstractProject)) { @@ -42,44 +43,22 @@ public void execute() { continue; } - TypetalkMessage.Emoji ball2emoji; - switch (project.getIconColor()) { - case RED: - case RED_ANIME: - ball2emoji = TypetalkMessage.Emoji.RAGE; - break; - case YELLOW: - case YELLOW_ANIME: - ball2emoji = TypetalkMessage.Emoji.CRY; - break; - case BLUE: - case BLUE_ANIME: - ball2emoji = TypetalkMessage.Emoji.SMILEY; - break; - case DISABLED: - case DISABLED_ANIME: - case NOTBUILT: - case NOTBUILT_ANIME: - ball2emoji = TypetalkMessage.Emoji.MASK; - break; - default: - ball2emoji = TypetalkMessage.Emoji.ASTONISHED; - } - messages.add(String.format(PROJECT_MESSAGE_FORMAT, ball2emoji.getSymbol(), project.getName(), project.getAbsoluteUrl())); + Emoji projectEmoji = new ResultSupport().convertProjectToEmoji(project); + messages.add(String.format(PROJECT_MESSAGE_FORMAT, projectEmoji.getSymbol(), project.getName(), project.getAbsoluteUrl())); } if (messages.isEmpty()) { messages.add("Project is not found"); - emoji = TypetalkMessage.Emoji.CRY; + CommandEmoji = Emoji.CRY; } else { messages.add(0, "Project list"); messages.add(""); - emoji = TypetalkMessage.Emoji.PAGE_FACING_UP; + CommandEmoji = Emoji.PAGE_FACING_UP; } ResponseParameter responseParameter = new ResponseParameter(ResponseParameter.flatMessages(messages)); responseParameter.setDescription("Command [ list ] is executed"); - responseParameter.setEmoji(emoji); + responseParameter.setEmoji(CommandEmoji); output(responseParameter); } diff --git a/src/test/groovy/org/jenkinsci/plugins/typetalk/TypetalkMessageSpec.groovy b/src/test/groovy/org/jenkinsci/plugins/typetalk/TypetalkMessageSpec.groovy index 861b167..45e5598 100644 --- a/src/test/groovy/org/jenkinsci/plugins/typetalk/TypetalkMessageSpec.groovy +++ b/src/test/groovy/org/jenkinsci/plugins/typetalk/TypetalkMessageSpec.groovy @@ -2,7 +2,8 @@ package org.jenkinsci.plugins.typetalk import hudson.model.AbstractBuild import hudson.model.Result -import org.jenkinsci.plugins.typetalk.api.TypetalkMessage +import org.jenkinsci.plugins.typetalk.support.Emoji +import org.jenkinsci.plugins.typetalk.support.ResultSupport import spock.lang.Specification import spock.lang.Unroll @@ -14,25 +15,25 @@ class TypetalkMessageSpec extends Specification { def build = makeMockBuild(result, previousResult) when: - def typetalkResult = TypetalkMessage.convertFromResult(build) + def typetalkResult = new ResultSupport().convertBuildToMessage(build) then: typetalkResult.emoji == emoji typetalkResult.message.contains(message) where: - previousResult | result || emoji | message - Result.SUCCESS | Result.SUCCESS || TypetalkMessage.Emoji.SMILEY | 'success' - Result.SUCCESS | Result.UNSTABLE || TypetalkMessage.Emoji.CRY | 'unstable' - Result.SUCCESS | Result.FAILURE || TypetalkMessage.Emoji.RAGE | 'failure' - Result.SUCCESS | Result.ABORTED || TypetalkMessage.Emoji.ASTONISHED | 'aborted' - Result.SUCCESS | Result.NOT_BUILT || TypetalkMessage.Emoji.ASTONISHED | 'Not built' - - Result.FAILURE | Result.SUCCESS || TypetalkMessage.Emoji.SMILEY | 'recovery' - Result.FAILURE | Result.UNSTABLE || TypetalkMessage.Emoji.CRY | 'unstable' - Result.FAILURE | Result.FAILURE || TypetalkMessage.Emoji.RAGE | 'failure' - Result.FAILURE | Result.ABORTED || TypetalkMessage.Emoji.ASTONISHED | 'aborted' - Result.FAILURE | Result.NOT_BUILT || TypetalkMessage.Emoji.ASTONISHED | 'Not built' + previousResult | result || emoji | message + Result.SUCCESS | Result.SUCCESS || Emoji.SMILEY | 'success' + Result.SUCCESS | Result.UNSTABLE || Emoji.CRY | 'unstable' + Result.SUCCESS | Result.FAILURE || Emoji.RAGE | 'failure' + Result.SUCCESS | Result.ABORTED || Emoji.ASTONISHED | 'aborted' + Result.SUCCESS | Result.NOT_BUILT || Emoji.ASTONISHED | 'Not built' + + Result.FAILURE | Result.SUCCESS || Emoji.SMILEY | 'recovery' + Result.FAILURE | Result.UNSTABLE || Emoji.CRY | 'unstable' + Result.FAILURE | Result.FAILURE || Emoji.RAGE | 'failure' + Result.FAILURE | Result.ABORTED || Emoji.ASTONISHED | 'aborted' + Result.FAILURE | Result.NOT_BUILT || Emoji.ASTONISHED | 'Not built' } def makeMockBuild(Result result, Result previousResult) {