TextResult.java revision c0f90a8f93546f4e9a708c44ac610f36b5e9b1f8
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.dumprendertree2; 18 19import android.os.Bundle; 20import android.os.Handler; 21import android.os.Message; 22import android.webkit.WebView; 23 24import name.fraser.neil.plaintext.diff_match_patch; 25 26import java.util.LinkedList; 27 28/** 29 * A result object for which the expected output is text. It does not have an image 30 * expected result. 31 * 32 * <p>Created if layoutTestController.dumpAsText() was called. 33 */ 34public class TextResult extends AbstractResult { 35 36 private static final int MSG_DOCUMENT_AS_TEXT = 0; 37 38 private String mExpectedResult; 39 private String mExpectedResultPath; 40 private String mActualResult; 41 private String mRelativePath; 42 private boolean mDidTimeOut; 43 private ResultCode mResultCode; 44 transient private Message mResultObtainedMsg; 45 46 private boolean mDumpChildFramesAsText; 47 48 transient private Handler mHandler = new Handler() { 49 @Override 50 public void handleMessage(Message msg) { 51 if (msg.what == MSG_DOCUMENT_AS_TEXT) { 52 mActualResult = (String)msg.obj; 53 mResultObtainedMsg.sendToTarget(); 54 } 55 } 56 }; 57 58 public TextResult(String relativePath) { 59 mRelativePath = relativePath; 60 } 61 62 public void setDumpChildFramesAsText(boolean dumpChildFramesAsText) { 63 mDumpChildFramesAsText = dumpChildFramesAsText; 64 } 65 66 /** 67 * Used to recreate the Result when received by the service. 68 * 69 * @param bundle 70 * bundle with data used to recreate the result 71 */ 72 public TextResult(Bundle bundle) { 73 mExpectedResult = bundle.getString("expectedTextualResult"); 74 mExpectedResultPath = bundle.getString("expectedTextualResultPath"); 75 mActualResult = bundle.getString("actualTextualResult"); 76 setAdditionalTextOutputString(bundle.getString("additionalTextOutputString")); 77 mRelativePath = bundle.getString("relativePath"); 78 mDidTimeOut = bundle.getBoolean("didTimeOut"); 79 } 80 81 @Override 82 public void clearResults() { 83 super.clearResults(); 84 mExpectedResult = null; 85 mActualResult = null; 86 } 87 88 @Override 89 public ResultCode getResultCode() { 90 if (mResultCode == null) { 91 if (mExpectedResult == null) { 92 mResultCode = AbstractResult.ResultCode.NO_EXPECTED_RESULT; 93 } else { 94 mResultCode = resultsMatch() ? AbstractResult.ResultCode.RESULTS_MATCH 95 : AbstractResult.ResultCode.RESULTS_DIFFER; 96 } 97 } 98 return mResultCode; 99 } 100 101 private boolean resultsMatch() { 102 assert mExpectedResult != null; 103 assert mActualResult != null; 104 // Trim leading and trailing empty lines, as other WebKit platforms do. 105 String leadingEmptyLines = "^\\n+"; 106 String trailingEmptyLines = "\\n+$"; 107 String trimmedExpectedResult = mExpectedResult.replaceFirst(leadingEmptyLines, "") 108 .replaceFirst(trailingEmptyLines, ""); 109 String trimmedActualResult = mActualResult.replaceFirst(leadingEmptyLines, "") 110 .replaceFirst(trailingEmptyLines, ""); 111 return trimmedExpectedResult.equals(trimmedActualResult); 112 } 113 114 @Override 115 public boolean didCrash() { 116 return false; 117 } 118 119 @Override 120 public boolean didTimeOut() { 121 return mDidTimeOut; 122 } 123 124 @Override 125 public void setDidTimeOut() { 126 mDidTimeOut = true; 127 } 128 129 @Override 130 public byte[] getActualImageResult() { 131 return null; 132 } 133 134 @Override 135 public String getActualTextResult() { 136 String additionalTextResultString = getAdditionalTextOutputString(); 137 if (additionalTextResultString != null) { 138 return additionalTextResultString+ mActualResult; 139 } 140 141 return mActualResult; 142 } 143 144 @Override 145 public void setExpectedImageResult(byte[] expectedResult) { 146 /** This method is not applicable to this type of result */ 147 } 148 149 @Override 150 public void setExpectedImageResultPath(String relativePath) { 151 /** This method is not applicable to this type of result */ 152 } 153 154 @Override 155 public String getExpectedImageResultPath() { 156 /** This method is not applicable to this type of result */ 157 return null; 158 } 159 160 @Override 161 public void setExpectedTextResultPath(String relativePath) { 162 mExpectedResultPath = relativePath; 163 } 164 165 @Override 166 public String getExpectedTextResultPath() { 167 return mExpectedResultPath; 168 } 169 170 @Override 171 public void setExpectedTextResult(String expectedResult) { 172 mExpectedResult = expectedResult; 173 } 174 175 @Override 176 public String getDiffAsHtml() { 177 StringBuilder html = new StringBuilder(); 178 html.append("<table class=\"visual_diff\">"); 179 html.append(" <tr class=\"headers\">"); 180 html.append(" <td colspan=\"2\">Expected result:</td>"); 181 html.append(" <td class=\"space\"></td>"); 182 html.append(" <td colspan=\"2\">Actual result:</td>"); 183 html.append(" </tr>"); 184 185 if (mExpectedResult == null || mActualResult == null) { 186 appendNullsHtml(html); 187 } else { 188 appendDiffHtml(html); 189 } 190 191 html.append(" <tr class=\"footers\">"); 192 html.append(" <td colspan=\"2\"></td>"); 193 html.append(" <td class=\"space\"></td>"); 194 html.append(" <td colspan=\"2\"></td>"); 195 html.append(" </tr>"); 196 html.append("</table>"); 197 198 return html.toString(); 199 } 200 201 private void appendDiffHtml(StringBuilder html) { 202 LinkedList<diff_match_patch.Diff> diffs = 203 new diff_match_patch().diff_main(mExpectedResult, mActualResult); 204 205 diffs = VisualDiffUtils.splitDiffsOnNewline(diffs); 206 207 LinkedList<String> expectedLines = new LinkedList<String>(); 208 LinkedList<Integer> expectedLineNums = new LinkedList<Integer>(); 209 LinkedList<String> actualLines = new LinkedList<String>(); 210 LinkedList<Integer> actualLineNums = new LinkedList<Integer>(); 211 212 VisualDiffUtils.generateExpectedResultLines(diffs, expectedLineNums, expectedLines); 213 VisualDiffUtils.generateActualResultLines(diffs, actualLineNums, actualLines); 214 215 html.append(VisualDiffUtils.getHtml(expectedLineNums, expectedLines, 216 actualLineNums, actualLines)); 217 } 218 219 private void appendNullsHtml(StringBuilder html) { 220 /** TODO: Create a separate row for each line of not null result */ 221 html.append(" <tr class=\"results\">"); 222 html.append(" <td class=\"line_count\">"); 223 html.append(" </td>"); 224 html.append(" <td class=\"line\">"); 225 if (mExpectedResult == null) { 226 html.append("Expected result was NULL"); 227 } else { 228 html.append(mExpectedResult.replace("\n", "<br />")); 229 } 230 html.append(" </td>"); 231 html.append(" <td class=\"space\"></td>"); 232 html.append(" <td class=\"line_count\">"); 233 html.append(" </td>"); 234 html.append(" <td class=\"line\">"); 235 if (mActualResult == null) { 236 html.append("Actual result was NULL"); 237 } else { 238 html.append(mActualResult.replace("\n", "<br />")); 239 } 240 html.append(" </td>"); 241 html.append(" </tr>"); 242 } 243 244 @Override 245 public TestType getType() { 246 return TestType.TEXT; 247 } 248 249 @Override 250 public void obtainActualResults(WebView webview, Message resultObtainedMsg) { 251 mResultObtainedMsg = resultObtainedMsg; 252 Message msg = mHandler.obtainMessage(MSG_DOCUMENT_AS_TEXT); 253 254 /** 255 * arg1 - should dump top frame as text 256 * arg2 - should dump child frames as text 257 */ 258 msg.arg1 = 1; 259 msg.arg2 = mDumpChildFramesAsText ? 1 : 0; 260 webview.documentAsText(msg); 261 } 262 263 @Override 264 public Bundle getBundle() { 265 Bundle bundle = new Bundle(); 266 bundle.putString("expectedTextualResult", mExpectedResult); 267 bundle.putString("expectedTextualResultPath", mExpectedResultPath); 268 bundle.putString("actualTextualResult", getActualTextResult()); 269 bundle.putString("additionalTextOutputString", getAdditionalTextOutputString()); 270 bundle.putString("relativePath", mRelativePath); 271 bundle.putBoolean("didTimeOut", mDidTimeOut); 272 bundle.putString("type", getType().name()); 273 return bundle; 274 } 275 276 @Override 277 public String getRelativePath() { 278 return mRelativePath; 279 } 280} 281