1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "js/CompilationAndEvaluation.h"
6 #include "js/Exception.h"
7 #include "js/GlobalObject.h"
8 #include "js/SourceText.h"
9 #include "jsapi-tests/tests.h"
10 #include "vm/ErrorReporting.h"
12 BEGIN_TEST(testErrorLineOfContext
) {
13 static const char16_t fullLineR
[] = u
"\n var x = @; \r ";
14 CHECK(testLineOfContextHasNoLineTerminator(fullLineR
, ' '));
16 static const char16_t fullLineN
[] = u
"\n var x = @; !\n ";
17 CHECK(testLineOfContextHasNoLineTerminator(fullLineN
, '!'));
19 static const char16_t fullLineLS
[] = u
"\n var x = @; +\u2028 ";
20 CHECK(testLineOfContextHasNoLineTerminator(fullLineLS
, '+'));
22 static const char16_t fullLinePS
[] = u
"\n var x = @; #\u2029 ";
23 CHECK(testLineOfContextHasNoLineTerminator(fullLinePS
, '#'));
25 static_assert(js::ErrorMetadata::lineOfContextRadius
== 60,
26 "current max count past offset is 60, hits 'X' below");
28 static const char16_t truncatedLine
[] =
29 u
"@ + 4567890123456789012345678901234567890123456789012345678XYZW\n";
30 CHECK(testLineOfContextHasNoLineTerminator(truncatedLine
, 'X'));
35 bool eval(const char16_t
* chars
, size_t len
, JS::MutableHandleValue rval
) {
36 JS::RealmOptions globalOptions
;
37 JS::RootedObject
global(
38 cx
, JS_NewGlobalObject(cx
, getGlobalClass(), nullptr,
39 JS::FireOnNewGlobalHook
, globalOptions
));
42 JSAutoRealm
ar(cx
, global
);
44 JS::SourceText
<char16_t
> srcBuf
;
45 CHECK(srcBuf
.init(cx
, chars
, len
, JS::SourceOwnership::Borrowed
));
47 JS::CompileOptions
options(cx
);
48 return JS::Evaluate(cx
, options
, srcBuf
, rval
);
52 bool testLineOfContextHasNoLineTerminator(const char16_t (&chars
)[N
],
53 char16_t expectedLast
) {
54 JS::RootedValue
rval(cx
);
55 CHECK(!eval(chars
, N
- 1, &rval
));
57 JS::ExceptionStack
exnStack(cx
);
58 CHECK(JS::StealPendingExceptionStack(cx
, &exnStack
));
60 JS::ErrorReportBuilder
report(cx
);
61 CHECK(report
.init(cx
, exnStack
, JS::ErrorReportBuilder::WithSideEffects
));
63 const auto* errorReport
= report
.report();
65 const char16_t
* lineOfContext
= errorReport
->linebuf();
66 size_t lineOfContextLength
= errorReport
->linebufLength();
68 CHECK(lineOfContext
[lineOfContextLength
] == '\0');
69 char16_t last
= lineOfContext
[lineOfContextLength
- 1];
70 CHECK(last
== expectedLast
);
74 END_TEST(testErrorLineOfContext
)