• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / httpunit / 656

06 Dec 2025 09:11PM UTC coverage: 80.452% (+0.02%) from 80.435%
656

push

github

hazendaz
[maven-release-plugin] prepare for next development iteration

3213 of 4105 branches covered (78.27%)

Branch coverage included in aggregate %.

8245 of 10137 relevant lines covered (81.34%)

0.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.62
/src/main/java/com/meterware/httpunit/javascript/ScriptingEngineImpl.java
1
/*
2
 * MIT License
3
 *
4
 * Copyright 2011-2025 Russell Gold
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
7
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
9
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions
12
 * of the Software.
13
 *
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
15
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
17
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18
 * DEALINGS IN THE SOFTWARE.
19
 */
20
package com.meterware.httpunit.javascript;
21

22
import com.meterware.httpunit.HttpUnitUtils;
23
import com.meterware.httpunit.ScriptException;
24
import com.meterware.httpunit.scripting.ScriptingEngine;
25

26
import java.util.ArrayList;
27
import java.util.Locale;
28

29
import org.mozilla.javascript.Context;
30
import org.mozilla.javascript.EcmaError;
31
import org.mozilla.javascript.EvaluatorException;
32
import org.mozilla.javascript.Function;
33
import org.mozilla.javascript.JavaScriptException;
34
import org.mozilla.javascript.ScriptableObject;
35
import org.mozilla.javascript.Undefined;
36

37
/**
38
 * The Class ScriptingEngineImpl.
39
 */
40
public abstract class ScriptingEngineImpl extends ScriptableObject implements ScriptingEngine {
1✔
41

42
    /** The Constant serialVersionUID. */
43
    private static final long serialVersionUID = 1L;
44

45
    /** The Constant NO_ARGS. */
46
    private static final Object[] NO_ARGS = {};
1✔
47

48
    /** The error messages. */
49
    private static ArrayList _errorMessages = new ArrayList<>();
1✔
50

51
    /**
52
     * clear the list of error Messages.
53
     */
54
    static public void clearErrorMessages() {
55
        _errorMessages.clear();
1✔
56
    }
1✔
57

58
    /**
59
     * access to the list of error Messages that were collected.
60
     *
61
     * @return the array with error Messages
62
     */
63
    static public String[] getErrorMessages() {
64
        return (String[]) _errorMessages.toArray(new String[_errorMessages.size()]);
1✔
65
    }
66

67
    /**
68
     * handle Exceptions.
69
     *
70
     * @param e
71
     *            - the exception to handle
72
     * @param badScript
73
     *            - the script that caused the problem
74
     */
75
    static public void handleScriptException(Exception e, String badScript) {
76
        String errorMessage = badScript == null ? e.getMessage() : badScript + " failed: " + e;
1✔
77
        if (!(e instanceof EcmaError) && !(e instanceof EvaluatorException) && !(e instanceof ScriptException)
1!
78
                && !(e instanceof JavaScriptException)) {
79
            HttpUnitUtils.handleException(e);
1✔
80
            throw new RuntimeException(errorMessage);
1✔
81
        }
82
        if (JavaScript.isThrowExceptionsOnError()) {
1✔
83
            HttpUnitUtils.handleException(e);
1✔
84
            if (e instanceof ScriptException) {
1✔
85
                throw (ScriptException) e;
1✔
86
            }
87
            throw new ScriptException(errorMessage);
1✔
88
        }
89
        _errorMessages.add(errorMessage);
1✔
90
    }
1✔
91

92
    // --------------------------------------- ScriptingEngine methods
93
    // ------------------------------------------------------
94

95
    @Override
96
    public boolean supportsScriptLanguage(String language) {
97
        return language == null || language.toLowerCase(Locale.ENGLISH).startsWith("javascript");
1✔
98
    }
99

100
    /**
101
     * run the given script
102
     *
103
     * @param language
104
     *            - the language of the script
105
     * @param script
106
     *            - the script to run
107
     */
108
    @Override
109
    public String runScript(String language, String script) {
110
        if (!supportsScriptLanguage(language)) {
1✔
111
            return "";
1✔
112
        }
113
        try {
114
            script = script.trim();
1✔
115
            if (script.startsWith("<!--")) {
1✔
116
                script = withoutFirstLine(script);
1✔
117
                if (script.endsWith("-->")) {
1✔
118
                    script = script.substring(0, script.lastIndexOf("-->"));
1✔
119
                }
120
            }
121
            Context context = Context.enter();
1✔
122
            context.initStandardObjects(null);
1✔
123
            context.evaluateString(this, script, "httpunit", 0, null);
1✔
124
            return getDocumentWriteBuffer();
1✔
125
        } catch (Exception e) {
×
126
            handleScriptException(e, "Script '" + script + "'");
×
127
            return "";
×
128
        } finally {
129
            discardDocumentWriteBuffer();
1✔
130
            Context.exit();
1✔
131
        }
132
    }
133

134
    /**
135
     * handle the event that has the given script attached by compiling the eventScript as a function and executing it
136
     *
137
     * @param eventScript
138
     *            - the script to use
139
     *
140
     * @deprecated since 1.7 - use doEventScript instead
141
     */
142
    @Deprecated
143
    @Override
144
    public boolean doEvent(String eventScript) {
145
        return doEventScript(eventScript);
×
146
    }
147

148
    /**
149
     * handle the event that has the given script attached by compiling the eventScript as a function and executing it
150
     *
151
     * @param eventScript
152
     *            - the script to use
153
     */
154
    @Override
155
    public boolean doEventScript(String eventScript) {
156
        if (eventScript.isEmpty()) {
1!
157
            return true;
×
158
        }
159
        try {
160
            Context context = Context.enter();
1✔
161
            context.initStandardObjects(null);
1✔
162
            context.setOptimizationLevel(-1);
1✔
163
            // wrap the eventScript into a function
164
            Function f = context.compileFunction(this, "function x() { " + eventScript + "}", "httpunit", 0, null);
1✔
165
            // call the function with no arguments
166
            Object result = f.call(context, this, this, NO_ARGS);
1✔
167
            // return the result of the function or false if it is not boolean
168
            return !(result instanceof Boolean) || ((Boolean) result).booleanValue();
1✔
169
        } catch (Exception e) {
1✔
170
            handleScriptException(e, "Event '" + eventScript + "'");
1✔
171
            return false;
1✔
172
        } finally {
173
            Context.exit();
1✔
174
        }
175
    }
176

177
    /**
178
     * get the event Handler script for the event e.g. onchange, onmousedown, onclick, onmouseup execute the script if
179
     * it's assigned by calling doEvent for the script
180
     *
181
     * @param eventName
182
     *            the event name
183
     *
184
     * @return true, if successful
185
     */
186
    @Override
187
    public boolean handleEvent(String eventName) {
188
        throw new RuntimeException("pseudo - abstract handleEvent called ");
×
189
    }
190

191
    /**
192
     * Evaluates the specified string as JavaScript. Will return null if the script has no return value.
193
     *
194
     * @param expression
195
     *            - the expression to evaluate
196
     */
197
    @Override
198
    public Object evaluateExpression(String expression) {
199
        try {
200
            Context context = Context.enter();
1✔
201
            context.initStandardObjects(null);
1✔
202
            Object result = context.evaluateString(this, expression, "httpunit", 0, null);
1✔
203
            return result == null || result instanceof Undefined ? null : result;
1!
204
        } catch (Exception e) {
1✔
205
            handleScriptException(e, "URL '" + expression + "'");
1✔
206
            return null;
1✔
207
        } finally {
208
            Context.exit();
1✔
209
        }
210
    }
211

212
    // ------------------------------------------ protected methods
213
    // ---------------------------------------------------------
214

215
    /**
216
     * Gets the document write buffer.
217
     *
218
     * @return the document write buffer
219
     */
220
    protected String getDocumentWriteBuffer() {
221
        throw new IllegalStateException("may not run runScript() from " + getClass());
×
222
    }
223

224
    /**
225
     * Discard document write buffer.
226
     */
227
    protected void discardDocumentWriteBuffer() {
228
        throw new IllegalStateException("may not run runScript() from " + getClass());
×
229
    }
230

231
    /**
232
     * Without first line.
233
     *
234
     * @param script
235
     *            the script
236
     *
237
     * @return the string
238
     */
239
    private String withoutFirstLine(String script) {
240
        for (int i = 0; i < script.length(); i++) {
1✔
241
            if (isLineTerminator(script.charAt(i))) {
1✔
242
                return script.substring(i).trim();
1✔
243
            }
244
        }
245
        return "";
1✔
246
    }
247

248
    /**
249
     * Checks if is line terminator.
250
     *
251
     * @param c
252
     *            the c
253
     *
254
     * @return true, if is line terminator
255
     */
256
    private boolean isLineTerminator(char c) {
257
        return c == 0x0A || c == 0x0D;
1!
258
    }
259
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc