Imported Upstream version 1.0.0
[platform/upstream/js.git] / js / src / jsapi-tests / testVersion.cpp
1 #include "tests.h"
2 #include "jsscript.h"
3 #include "jscntxt.h"
4
5 using namespace js;
6
7 struct VersionFixture;
8
9 /*
10  * Fast-native callbacks for use from JS.
11  * They set their results on the current fixture instance.
12  */
13
14 static VersionFixture *callbackData = NULL;
15
16 JSBool CheckVersionHasXML(JSContext *cx, uintN argc, jsval *vp);
17 JSBool DisableXMLOption(JSContext *cx, uintN argc, jsval *vp);
18 JSBool CallSetVersion17(JSContext *cx, uintN argc, jsval *vp);
19 JSBool CheckNewScriptNoXML(JSContext *cx, uintN argc, jsval *vp);
20 JSBool OverrideVersion15(JSContext *cx, uintN argc, jsval *vp);
21 JSBool CaptureVersion(JSContext *cx, uintN argc, jsval *vp);
22 JSBool CheckOverride(JSContext *cx, uintN argc, jsval *vp);
23 JSBool EvalScriptVersion16(JSContext *cx, uintN argc, jsval *vp);
24
25 struct VersionFixture : public JSAPITest
26 {
27     JSVersion captured;
28
29     virtual bool init() {
30         JSAPITest::init();
31         callbackData = this;
32         captured = JSVERSION_UNKNOWN;
33         return JS_DefineFunction(cx, global, "checkVersionHasXML", CheckVersionHasXML, 0, 0) &&
34                JS_DefineFunction(cx, global, "disableXMLOption", DisableXMLOption, 0, 0) &&
35                JS_DefineFunction(cx, global, "callSetVersion17", CallSetVersion17, 0, 0) &&
36                JS_DefineFunction(cx, global, "checkNewScriptNoXML", CheckNewScriptNoXML, 0, 0) &&
37                JS_DefineFunction(cx, global, "overrideVersion15", OverrideVersion15, 0, 0) &&
38                JS_DefineFunction(cx, global, "captureVersion", CaptureVersion, 0, 0) &&
39                JS_DefineFunction(cx, global, "checkOverride", CheckOverride, 1, 0) &&
40                JS_DefineFunction(cx, global, "evalScriptVersion16",
41                                  EvalScriptVersion16, 0, 0);
42     }
43
44     JSObject *fakeScript(const char *contents, size_t length) {
45         return JS_CompileScript(cx, global, contents, length, "<test>", 1);
46     }
47
48     bool hasXML(uintN version) {
49         return VersionHasXML(JSVersion(version));
50     }
51
52     bool hasXML(JSScript *script) {
53         return hasXML(script->getVersion());
54     }
55
56     bool hasXML() {
57         return OptionsHasXML(JS_GetOptions(cx));
58     }
59
60     bool checkOptionsHasNoXML() {
61         CHECK(!OptionsHasXML(JS_GetOptions(cx)));
62         return true;
63     }
64
65     bool disableXMLOption() {
66         JS_SetOptions(cx, JS_GetOptions(cx) & ~JSOPTION_XML);
67         return true;
68     }
69
70     bool checkVersionIsOverridden() {
71         CHECK(cx->isVersionOverridden());
72         return true;
73     }
74
75     /* Check that script compilation results in a version without XML. */
76     bool checkNewScriptNoXML() {
77         JSObject *scriptObj = fakeScript("", 0);
78         CHECK(scriptObj);
79         CHECK(!hasXML(JS_GetScriptFromObject(scriptObj)->getVersion()));
80         return true;
81     }
82
83     bool checkVersionHasXML() {
84         CHECK(VersionHasXML(cx->findVersion()));
85         return true;
86     }
87
88     bool setVersion(JSVersion version) {
89         CHECK(JS_GetVersion(cx) != version);
90         JS_SetVersion(cx, version);
91         return true;
92     }
93
94     bool evalVersion(const jschar *chars, size_t len, JSVersion version) {
95         CHECK(JS_GetVersion(cx) != version);
96         jsval rval;
97         CHECK(JS_EvaluateUCScriptForPrincipalsVersion(
98                 cx, global, NULL, chars, len, "<test>", 0, &rval, version));
99         return true;
100     }
101
102     bool toggleXML(bool shouldEnable) {
103         CHECK(hasXML() == !shouldEnable);
104         JS_ToggleOptions(cx, JSOPTION_XML);
105         CHECK(hasXML() == shouldEnable);
106         return true;
107     }
108
109     bool disableXML() {
110         return toggleXML(false);
111     }
112
113     bool enableXML() {
114         return toggleXML(true);
115     }
116 };
117
118 /* Callbacks to throw into JS-land. */
119
120 JSBool
121 CallSetVersion17(JSContext *cx, uintN argc, jsval *vp)
122 {
123     return callbackData->setVersion(JSVERSION_1_7);
124 }
125
126 JSBool
127 CheckVersionHasXML(JSContext *cx, uintN argc, jsval *vp)
128 {
129     return callbackData->checkVersionHasXML();
130 }
131
132 JSBool
133 DisableXMLOption(JSContext *cx, uintN argc, jsval *vp)
134 {
135     return callbackData->disableXMLOption();
136 }
137
138 JSBool
139 CheckNewScriptNoXML(JSContext *cx, uintN argc, jsval *vp)
140 {
141     return callbackData->checkNewScriptNoXML();
142 }
143
144 JSBool
145 OverrideVersion15(JSContext *cx, uintN argc, jsval *vp)
146 {
147     if (!callbackData->setVersion(JSVERSION_1_5))
148         return false;
149     return callbackData->checkVersionIsOverridden();
150 }
151
152 JSBool
153 EvalScriptVersion16(JSContext *cx, uintN argc, jsval *vp)
154 {
155     JS_ASSERT(argc == 1);
156     jsval *argv = JS_ARGV(cx, vp);
157     JS_ASSERT(JSVAL_IS_STRING(argv[0]));
158     JSString *str = JSVAL_TO_STRING(argv[0]);
159     const jschar *chars = str->getChars(cx);
160     JS_ASSERT(chars);
161     size_t len = str->length();
162     return callbackData->evalVersion(chars, len, JSVERSION_1_6);
163 }
164
165 JSBool
166 CaptureVersion(JSContext *cx, uintN argc, jsval *vp)
167 {
168     callbackData->captured = JS_GetVersion(cx);
169     return true;
170 }
171
172 JSBool
173 CheckOverride(JSContext *cx, uintN argc, jsval *vp)
174 {
175     JS_ASSERT(argc == 1);
176     jsval *argv = JS_ARGV(cx, vp);
177     JS_ASSERT(JSVAL_IS_BOOLEAN(argv[0]));
178     bool shouldHaveOverride = !!JSVAL_TO_BOOLEAN(argv[0]);
179     return shouldHaveOverride == cx->isVersionOverridden();
180 }
181
182 /*
183  * See bug 611462. We are checking that the XML option setting from a JSAPI
184  * call is propagated to newly compiled scripts, instead of inheriting the XML
185  * setting from a script on the stack.
186  */
187 BEGIN_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
188 {
189     callbackData = this;
190
191     /* Enable XML and compile a script to activate. */
192     enableXML();
193     const char toActivateChars[] =
194         "checkVersionHasXML();"
195         "disableXMLOption();"
196         "callSetVersion17();"
197         "checkNewScriptNoXML();";
198     JSObject *toActivate = fakeScript(toActivateChars, sizeof(toActivateChars) - 1);
199     CHECK(toActivate);
200     CHECK(hasXML(JS_GetScriptFromObject(toActivate)));
201
202     disableXML();
203
204     /* Activate the script. */
205     jsval dummy;
206     CHECK(JS_ExecuteScript(cx, global, toActivate, &dummy));
207     return true;
208 }
209 END_FIXTURE_TEST(VersionFixture, testOptionsAreUsedForVersionFlags)
210
211 /*
212  * When re-entering the virtual machine through a *Version API the version
213  * is no longer forced -- it continues with its natural push/pop oriented
214  * version progression.  This is maintained by the |AutoVersionAPI| class in
215  * jsapi.cpp.
216  */
217 BEGIN_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
218 {
219     EXEC("overrideVersion15(); evalScriptVersion16('checkOverride(false); captureVersion()');");
220     CHECK(captured == JSVERSION_1_6);
221
222     /* 
223      * Override gets propagated to default version as non-override when you leave the VM's execute
224      * call.
225      */
226     CHECK(JS_GetVersion(cx) == JSVERSION_1_5);
227     CHECK(!cx->isVersionOverridden());
228     return true;
229 }
230 END_FIXTURE_TEST(VersionFixture, testEntryLosesOverride)
231
232 /* 
233  * EvalScriptVersion does not propagate overrides to its caller, it
234  * restores things exactly as they were before the call. This is as opposed to
235  * the normal (no Version suffix) API which propagates overrides
236  * to the caller.
237  */
238 BEGIN_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
239 {
240     CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
241     EXEC(
242         "checkOverride(false);"
243         "evalScriptVersion16('overrideVersion15();');"
244         "checkOverride(false);"
245         "captureVersion();"
246     );
247     CHECK(captured == JSVERSION_ECMA_5);
248     return true;
249 }
250 END_FIXTURE_TEST(VersionFixture, testReturnLosesOverride)
251
252 BEGIN_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)
253 {
254     CHECK(JS_GetVersion(cx) == JSVERSION_ECMA_5);
255     EXEC(
256         "checkOverride(false);"
257         "eval('overrideVersion15();');"
258         "checkOverride(true);"
259         "captureVersion();"
260     );
261     CHECK(captured == JSVERSION_1_5);
262     return true;
263 }
264 END_FIXTURE_TEST(VersionFixture, testEvalPropagatesOverride)