• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TextResult(String relativePath)59     public TextResult(String relativePath) {
60         mRelativePath = relativePath;
61     }
62 
setDumpChildFramesAsText(boolean dumpChildFramesAsText)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      */
TextResult(Bundle bundle)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
clearResults()83     public void clearResults() {
84         super.clearResults();
85         mExpectedResult = null;
86         mActualResult = null;
87     }
88 
89     @Override
getResultCode()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 
resultsMatch()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
didCrash()112     public boolean didCrash() {
113         return false;
114     }
115 
116     @Override
didTimeOut()117     public boolean didTimeOut() {
118         return mDidTimeOut;
119     }
120 
121     @Override
setDidTimeOut()122     public void setDidTimeOut() {
123         mDidTimeOut = true;
124     }
125 
126     @Override
getActualImageResult()127     public byte[] getActualImageResult() {
128         return null;
129     }
130 
131     @Override
getActualTextResult()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
setExpectedImageResult(byte[] expectedResult)142     public void setExpectedImageResult(byte[] expectedResult) {
143         /** This method is not applicable to this type of result */
144     }
145 
146     @Override
setExpectedImageResultPath(String relativePath)147     public void setExpectedImageResultPath(String relativePath) {
148         /** This method is not applicable to this type of result */
149     }
150 
151     @Override
getExpectedImageResultPath()152     public String getExpectedImageResultPath() {
153         /** This method is not applicable to this type of result */
154         return null;
155     }
156 
157     @Override
setExpectedTextResultPath(String relativePath)158     public void setExpectedTextResultPath(String relativePath) {
159         mExpectedResultPath = relativePath;
160     }
161 
162     @Override
getExpectedTextResultPath()163     public String getExpectedTextResultPath() {
164         return mExpectedResultPath;
165     }
166 
167     @Override
setExpectedTextResult(String expectedResult)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
getDiffAsHtml()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 
appendDiffHtml(StringBuilder html)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
getType()222     public TestType getType() {
223         return TestType.TEXT;
224     }
225 
226     @Override
obtainActualResults(WebView webview, Message resultObtainedMsg)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
getBundle()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
getRelativePath()254     public String getRelativePath() {
255         return mRelativePath;
256     }
257 }
258