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 import android.webkit.WebViewClassic;
     24 
     25 import name.fraser.neil.plaintext.diff_match_patch;
     26 
     27 import java.util.LinkedList;
     28 
     29 /**
     30  * A result object for which the expected output is text. It does not have an image
     31  * expected result.
     32  *
     33  * <p>Created if layoutTestController.dumpAsText() was called.
     34  */
     35 public class TextResult extends AbstractResult {
     36 
     37     private static final int MSG_DOCUMENT_AS_TEXT = 0;
     38 
     39     private String mExpectedResult;
     40     private String mExpectedResultPath;
     41     private String mActualResult;
     42     private String mRelativePath;
     43     private boolean mDidTimeOut;
     44     private ResultCode mResultCode;
     45     transient private Message mResultObtainedMsg;
     46 
     47     private boolean mDumpChildFramesAsText;
     48 
     49     transient private Handler mHandler = new Handler() {
     50         @Override
     51         public void handleMessage(Message msg) {
     52             if (msg.what == MSG_DOCUMENT_AS_TEXT) {
     53                 mActualResult = (String)msg.obj;
     54                 mResultObtainedMsg.sendToTarget();
     55             }
     56         }
     57     };
     58 
     59     public TextResult(String relativePath) {
     60         mRelativePath = relativePath;
     61     }
     62 
     63     public void setDumpChildFramesAsText(boolean dumpChildFramesAsText) {
     64         mDumpChildFramesAsText = dumpChildFramesAsText;
     65     }
     66 
     67     /**
     68      * Used to recreate the Result when received by the service.
     69      *
     70      * @param bundle
     71      *      bundle with data used to recreate the result
     72      */
     73     public TextResult(Bundle bundle) {
     74         mExpectedResult = bundle.getString("expectedTextualResult");
     75         mExpectedResultPath = bundle.getString("expectedTextualResultPath");
     76         mActualResult = bundle.getString("actualTextualResult");
     77         setAdditionalTextOutputString(bundle.getString("additionalTextOutputString"));
     78         mRelativePath = bundle.getString("relativePath");
     79         mDidTimeOut = bundle.getBoolean("didTimeOut");
     80     }
     81 
     82     @Override
     83     public void clearResults() {
     84         super.clearResults();
     85         mExpectedResult = null;
     86         mActualResult = null;
     87     }
     88 
     89     @Override
     90     public ResultCode getResultCode() {
     91         if (mResultCode == null) {
     92             mResultCode = resultsMatch() ? AbstractResult.ResultCode.RESULTS_MATCH
     93                     : AbstractResult.ResultCode.RESULTS_DIFFER;
     94         }
     95         return mResultCode;
     96     }
     97 
     98     private boolean resultsMatch() {
     99         assert mExpectedResult != null;
    100         assert mActualResult != null;
    101         // Trim leading and trailing empty lines, as other WebKit platforms do.
    102         String leadingEmptyLines = "^\\n+";
    103         String trailingEmptyLines = "\\n+$";
    104         String trimmedExpectedResult = mExpectedResult.replaceFirst(leadingEmptyLines, "")
    105                 .replaceFirst(trailingEmptyLines, "");
    106         String trimmedActualResult = mActualResult.replaceFirst(leadingEmptyLines, "")
    107                 .replaceFirst(trailingEmptyLines, "");
    108         return trimmedExpectedResult.equals(trimmedActualResult);
    109     }
    110 
    111     @Override
    112     public boolean didCrash() {
    113         return false;
    114     }
    115 
    116     @Override
    117     public boolean didTimeOut() {
    118         return mDidTimeOut;
    119     }
    120 
    121     @Override
    122     public void setDidTimeOut() {
    123         mDidTimeOut = true;
    124     }
    125 
    126     @Override
    127     public byte[] getActualImageResult() {
    128         return null;
    129     }
    130 
    131     @Override
    132     public String getActualTextResult() {
    133         String additionalTextResultString = getAdditionalTextOutputString();
    134         if (additionalTextResultString != null) {
    135             return additionalTextResultString + mActualResult;
    136         }
    137 
    138         return mActualResult;
    139     }
    140 
    141     @Override
    142     public void setExpectedImageResult(byte[] expectedResult) {
    143         /** This method is not applicable to this type of result */
    144     }
    145 
    146     @Override
    147     public void setExpectedImageResultPath(String relativePath) {
    148         /** This method is not applicable to this type of result */
    149     }
    150 
    151     @Override
    152     public String getExpectedImageResultPath() {
    153         /** This method is not applicable to this type of result */
    154         return null;
    155     }
    156 
    157     @Override
    158     public void setExpectedTextResultPath(String relativePath) {
    159         mExpectedResultPath = relativePath;
    160     }
    161 
    162     @Override
    163     public String getExpectedTextResultPath() {
    164         return mExpectedResultPath;
    165     }
    166 
    167     @Override
    168     public void setExpectedTextResult(String expectedResult) {
    169         // For text results, we use an empty string for the expected result when none is
    170         // present, as other WebKit platforms do.
    171         mExpectedResult = expectedResult == null ? "" : expectedResult;
    172     }
    173 
    174     @Override
    175     public String getDiffAsHtml() {
    176         assert mExpectedResult != null;
    177         assert mActualResult != null;
    178 
    179         StringBuilder html = new StringBuilder();
    180         html.append("<table class=\"visual_diff\">");
    181         html.append("    <tr class=\"headers\">");
    182         html.append("        <td colspan=\"2\">Expected result:</td>");
    183         html.append("        <td class=\"space\"></td>");
    184         html.append("        <td colspan=\"2\">Actual result:</td>");
    185         html.append("    </tr>");
    186 
    187         appendDiffHtml(html);
    188 
    189         html.append("    <tr class=\"footers\">");
    190         html.append("        <td colspan=\"2\"></td>");
    191         html.append("        <td class=\"space\"></td>");
    192         html.append("        <td colspan=\"2\"></td>");
    193         html.append("    </tr>");
    194         html.append("</table>");
    195 
    196         return html.toString();
    197     }
    198 
    199     private void appendDiffHtml(StringBuilder html) {
    200         LinkedList<diff_match_patch.Diff> diffs =
    201                 new diff_match_patch().diff_main(mExpectedResult, mActualResult);
    202 
    203         diffs = VisualDiffUtils.splitDiffsOnNewline(diffs);
    204 
    205         LinkedList<String> expectedLines = new LinkedList<String>();
    206         LinkedList<Integer> expectedLineNums = new LinkedList<Integer>();
    207         LinkedList<String> actualLines = new LinkedList<String>();
    208         LinkedList<Integer> actualLineNums = new LinkedList<Integer>();
    209 
    210         VisualDiffUtils.generateExpectedResultLines(diffs, expectedLineNums, expectedLines);
    211         VisualDiffUtils.generateActualResultLines(diffs, actualLineNums, actualLines);
    212         // TODO: We should use a map for each line number and lines pair.
    213         assert expectedLines.size() == expectedLineNums.size();
    214         assert actualLines.size() == actualLineNums.size();
    215         assert expectedLines.size() == actualLines.size();
    216 
    217         html.append(VisualDiffUtils.getHtml(expectedLineNums, expectedLines,
    218                 actualLineNums, actualLines));
    219     }
    220 
    221     @Override
    222     public TestType getType() {
    223         return TestType.TEXT;
    224     }
    225 
    226     @Override
    227     public void obtainActualResults(WebView webview, Message resultObtainedMsg) {
    228         mResultObtainedMsg = resultObtainedMsg;
    229         Message msg = mHandler.obtainMessage(MSG_DOCUMENT_AS_TEXT);
    230 
    231         /**
    232          * arg1 - should dump top frame as text
    233          * arg2 - should dump child frames as text
    234          */
    235         msg.arg1 = 1;
    236         msg.arg2 = mDumpChildFramesAsText ? 1 : 0;
    237         WebViewClassic.fromWebView(webview).documentAsText(msg);
    238     }
    239 
    240     @Override
    241     public Bundle getBundle() {
    242         Bundle bundle = new Bundle();
    243         bundle.putString("expectedTextualResult", mExpectedResult);
    244         bundle.putString("expectedTextualResultPath", mExpectedResultPath);
    245         bundle.putString("actualTextualResult", getActualTextResult());
    246         bundle.putString("additionalTextOutputString", getAdditionalTextOutputString());
    247         bundle.putString("relativePath", mRelativePath);
    248         bundle.putBoolean("didTimeOut", mDidTimeOut);
    249         bundle.putString("type", getType().name());
    250         return bundle;
    251     }
    252 
    253     @Override
    254     public String getRelativePath() {
    255         return mRelativePath;
    256     }
    257 }
    258