|
1 === JSAPI Test Suite |
|
2 |
|
3 The tests in this directory exercise the JSAPI. |
|
4 |
|
5 |
|
6 --- Building and running the tests |
|
7 |
|
8 If you built JS, you already built the tests. |
|
9 |
|
10 If you did `make check` in your JS objdir, you already ran them. |
|
11 |
|
12 The tests are built by default when you build JS. All the tests are compiled |
|
13 into a single binary named jsapi-tests. They all run in a single process. |
|
14 |
|
15 To run the tests in a debugger: |
|
16 |
|
17 cd $OBJDIR/jsapi-tests |
|
18 gdb ./jsapi-tests |
|
19 |
|
20 |
|
21 --- Creating new tests |
|
22 |
|
23 1. You can either add to an existing test*.cpp file or make a new one. |
|
24 Copy an existing test and replace the body with your test code. |
|
25 The test harness provides `cx`, `rt`, and `global` for your use. |
|
26 |
|
27 2. If you made a new .cpp file, add it to the CPPSRCS list in Makefile.in. |
|
28 |
|
29 |
|
30 --- Writing test code |
|
31 |
|
32 Here is a sample test: |
|
33 |
|
34 #include "tests.h" |
|
35 |
|
36 BEGIN_TEST(testIntString_bug515273) |
|
37 { |
|
38 jsval v; |
|
39 EVAL("'42';", &v); |
|
40 |
|
41 JSString *str = JSVAL_TO_STRING(v); |
|
42 const char *bytes = JS_GetStringBytes(str); |
|
43 CHECK(strcmp(bytes, "42") == 0); |
|
44 return true; |
|
45 } |
|
46 END_TEST(testIntString_bug515273) |
|
47 |
|
48 The BEGIN_TEST and END_TEST macros bracket each test. By convention, the test |
|
49 name is <testFilename>_<detail>. (The above test is in testIntString.cpp.) |
|
50 |
|
51 The curly braces are required. This block is the body of a C++ member function |
|
52 that returns bool. The test harness calls this member function |
|
53 automatically. If the function returns true, the test passes. False, it fails. |
|
54 |
|
55 JSAPI tests often need extra global C/C++ code: a JSClass, a getter or setter |
|
56 function, a resolve hook. Put these before the BEGIN_TEST macro. |
|
57 |
|
58 The body of the test can use these member variables and macros, defined in |
|
59 tests.h: |
|
60 |
|
61 JSRuntime *rt; |
|
62 JSContext *cx; |
|
63 JSObject *global; |
|
64 |
|
65 The test framework creates these fresh for each test. The default |
|
66 environment has reasonable default settings, including |
|
67 JSOPTION_VAROBJFIX, JSOPTION_JIT, a global object of a class with |
|
68 JSCLASS_GLOBAL_FLAGS, and an error reporter that prints to stderr. |
|
69 See also "Custom test setup" below. |
|
70 |
|
71 EXEC(const char *code); |
|
72 |
|
73 Execute some JS code in global scope, using JS_EvaluateScript. Return |
|
74 false if that fails. (This means that if the code throws an uncaught JS |
|
75 exception, the test fails.) |
|
76 |
|
77 EVAL(const char *code, jsval *vp); |
|
78 |
|
79 Same as EXEC, but store the result value in *vp. |
|
80 |
|
81 CHECK(bool cond); |
|
82 |
|
83 If the condition is not true, print an error message and return false, |
|
84 failing the test. |
|
85 |
|
86 CHECK_SAME(jsval a, jsval b); |
|
87 |
|
88 If a and b are different values, print an error message and return |
|
89 false, failing the test. |
|
90 |
|
91 This is like CHECK(sameValue(a, b)) but with a more detailed error |
|
92 message. See sameValue below. |
|
93 |
|
94 bool knownFail; |
|
95 |
|
96 Set this to true if your test is known to fail. The test runner will |
|
97 print a TEST-KNOWN-FAIL line rather than a TEST-UNEXPECTED-FAIL |
|
98 line. This way you can check in a test illustrating a bug ahead of the |
|
99 fix. |
|
100 |
|
101 If your test actually crashes the process or triggers an assertion, |
|
102 this of course will not help, so you should add something like |
|
103 |
|
104 knownFail = true; // see bug 123456 |
|
105 return false; // the code below crashes! |
|
106 |
|
107 as the first two lines of the test. |
|
108 |
|
109 bool isNegativeZero(jsval v); |
|
110 bool isNaN(jsval v); |
|
111 |
|
112 Self-explanatory. |
|
113 |
|
114 bool sameValue(jsval v1, jsval v2); |
|
115 |
|
116 True if v1 and v2 are the same value according to the ES5 SameValue() |
|
117 function, to wit: |
|
118 |
|
119 SameValue(NaN, NaN) is true. |
|
120 SameValue(-0, 0) is false. |
|
121 Otherwise SameValue(a, b) iff a === b. |
|
122 |
|
123 |
|
124 --- Custom test setup |
|
125 |
|
126 Before executing each test, the test framework calls the tests' init() member |
|
127 function, which populates the rt, cx, and global member variables. |
|
128 |
|
129 A test can customize the test setup process by overloading virtual member |
|
130 functions, like this: |
|
131 |
|
132 const JSClass globalClassWithResolve = { ... }; |
|
133 |
|
134 BEGIN_TEST(testGlobalResolveHook) |
|
135 { |
|
136 RootedValue v; |
|
137 EVAL("v", v.address()); |
|
138 CHECK_SAME(v, JSVAL_VOID); |
|
139 return true; |
|
140 } |
|
141 |
|
142 // Other class members can go here. |
|
143 |
|
144 // This one overloads a base-class method. |
|
145 virtual JSClass *getGlobalJSClass() { |
|
146 return &globalClassWithResolve; |
|
147 } |
|
148 END_TEST(testGlobalResolveHook) |
|
149 |
|
150 The overloadable member functions are: |
|
151 |
|
152 virtual bool init(); |
|
153 virtual void uninit(); |
|
154 virtual JSRuntime * createRuntime(); |
|
155 virtual JSContext * createContext(); |
|
156 virtual JSClass * getGlobalClass(); |
|
157 virtual JSObject * createGlobal(); |
|
158 |