Home | History | Annotate | Download | only in dumprendertree2
      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 
     17 package com.android.dumprendertree2;
     18 
     19 import android.os.Bundle;
     20 import android.os.Handler;
     21 import android.os.Message;
     22 import android.webkit.WebView;
     23 
     24 import name.fraser.neil.plaintext.diff_match_patch;
     25 
     26 import 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  */
     34 public 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             mResultCode = resultsMatch() ? AbstractResult.ResultCode.RESULTS_MATCH
     92                     : AbstractResult.ResultCode.RESULTS_DIFFER;
     93         }
     94         return mResultCode;
     95     }
     96 
     97     private boolean resultsMatch() {
     98         assert mExpectedResult != null;
     99         assert mActualResult != null;
    100         // Trim leading and trailing empty lines, as other WebKit platforms do.
    101         String leadingEmptyLines = "^\\n+";
    102         String trailingEmptyLines = "\\n+$";
    103         String trimmedExpectedResult = mExpectedResult.replaceFirst(leadingEmptyLines, "")
    104                 .replaceFirst(trailingEmptyLines, "");
    105         String trimmedActualResult = mActualResult.replaceFirst(leadingEmptyLines, "")
    106                 .replaceFirst(trailingEmptyLines, "");
    107         return trimmedExpectedResult.equals(trimmedActualResult);
    108     }
    109 
    110     @Override
    111     public boolean didCrash() {
    112         return false;
    113     }
    114 
    115     @Override
    116     public boolean didTimeOut() {
    117         return mDidTimeOut;
    118     }
    119 
    120     @Override
    121     public void setDidTimeOut() {
    122         mDidTimeOut = true;
    123     }
    124 
    125     @Override
    126     public byte[] getActualImageResult() {
    127         return null;
    128     }
    129 
    130     @Override
    131     public String getActualTextResult() {
    132         String additionalTextResultString = getAdditionalTextOutputString();
    133         if (additionalTextResultString != null) {
    134             return additionalTextResultString + mActualResult;
    135         }
    136 
    137         return mActualResult;
    138     }
    139 
    140     @Override
    141     public void setExpectedImageResult(byte[] expectedResult) {
    142         /** This method is not applicable to this type of result */
    143     }
    144 
    145     @Override
    146     public void setExpectedImageResultPath(String relativePath) {
    147         /** This method is not applicable to this type of result */
    148     }
    149 
    150     @Override
    151     public String getExpectedImageResultPath() {
    152         /** This method is not applicable to this type of result */
    153         return null;
    154     }
    155 
    156     @Override
    157     public void setExpectedTextResultPath(String relativePath) {
    158         mExpectedResultPath = relativePath;
    159     }
    160 
    161     @Override
    162     public String getExpectedTextResultPath() {
    163         return mExpectedResultPath;
    164     }
    165 
    166     @Override
    167     public void setExpectedTextResult(String expectedResult) {
    168         // For text results, we use an empty string for the expected result when none is
    169         // present, as other WebKit platforms do.
    170         mExpectedResult = expectedResult == null ? "" : expectedResult;
    171     }
    172 
    173     @Override
    174     public String getDiffAsHtml() {
    175         assert mExpectedResult != null;
    176         assert mActualResult != null;
    177 
    178         StringBuilder html = new StringBuilder();
    179         html.append("<table class=\"visual_diff\">");
    180         html.append("    <tr class=\"headers\">");
    181         html.append("        <td colspan=\"2\">Expected result:</td>");
    182         html.append("        <td class=\"space\"></td>");
    183         html.append("        <td colspan=\"2\">Actual result:</td>");
    184         html.append("    </tr>");
    185 
    186         appendDiffHtml(html);
    187 
    188         html.append("    <tr class=\"footers\">");
    189         html.append("        <td colspan=\"2\"></td>");
    190         html.append("        <td class=\"space\"></td>");
    191         html.append("        <td colspan=\"2\"></td>");
    192         html.append("    </tr>");
    193         html.append("</table>");
    194 
    195         return html.toString();
    196     }
    197 
    198     private void appendDiffHtml(StringBuilder html) {
    199         LinkedList<diff_match_patch.Diff> diffs =
    200                 new diff_match_patch().diff_main(mExpectedResult, mActualResult);
    201 
    202         diffs = VisualDiffUtils.splitDiffsOnNewline(diffs);
    203 
    204         LinkedList<String> expectedLines = new LinkedList<String>();
    205         LinkedList<Integer> expectedLineNums = new LinkedList<Integer>();
    206         LinkedList<String> actualLines = new LinkedList<String>();
    207         LinkedList<Integer> actualLineNums = new LinkedList<Integer>();
    208 
    209         VisualDiffUtils.generateExpectedResultLines(diffs, expectedLineNums, expectedLines);
    210         VisualDiffUtils.generateActualResultLines(diffs, actualLineNums, actualLines);
    211         // TODO: We should use a map for each line number and lines pair.
    212         assert expectedLines.size() == expectedLineNums.size();
    213         assert actualLines.size() == actualLineNums.size();
    214         assert expectedLines.size() == actualLines.size();
    215 
    216         html.append(VisualDiffUtils.getHtml(expectedLineNums, expectedLines,
    217                 actualLineNums, actualLines));
    218     }
    219 
    220     @Override
    221     public TestType getType() {
    222         return TestType.TEXT;
    223     }
    224 
    225     @Override
    226     public void obtainActualResults(WebView webview, Message resultObtainedMsg) {
    227         mResultObtainedMsg = resultObtainedMsg;
    228         Message msg = mHandler.obtainMessage(MSG_DOCUMENT_AS_TEXT);
    229 
    230         /**
    231          * arg1 - should dump top frame as text
    232          * arg2 - should dump child frames as text
    233          */
    234         msg.arg1 = 1;
    235         msg.arg2 = mDumpChildFramesAsText ? 1 : 0;
    236         webview.documentAsText(msg);
    237     }
    238 
    239     @Override
    240     public Bundle getBundle() {
    241         Bundle bundle = new Bundle();
    242         bundle.putString("expectedTextualResult", mExpectedResult);
    243         bundle.putString("expectedTextualResultPath", mExpectedResultPath);
    244         bundle.putString("actualTextualResult", getActualTextResult());
    245         bundle.putString("additionalTextOutputString", getAdditionalTextOutputString());
    246         bundle.putString("relativePath", mRelativePath);
    247         bundle.putBoolean("didTimeOut", mDidTimeOut);
    248         bundle.putString("type", getType().name());
    249         return bundle;
    250     }
    251 
    252     @Override
    253     public String getRelativePath() {
    254         return mRelativePath;
    255     }
    256 }
    257