summaryrefslogtreecommitdiff
path: root/Tests/LibJS/test-js.cpp
blob: f9a9dd38cd26a38c43da8d2293c1dc66a5975d8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
 * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <LibTest/JavaScriptTestRunner.h>

TEST_ROOT("Userland/Libraries/LibJS/Tests");

TESTJS_PROGRAM_FLAG(test262_parser_tests, "Run test262 parser tests", "test262-parser-tests", 0);

TESTJS_GLOBAL_FUNCTION(is_strict_mode, isStrictMode, 0)
{
    return JS::Value(vm.in_strict_mode());
}

TESTJS_GLOBAL_FUNCTION(can_parse_source, canParseSource)
{
    auto source = vm.argument(0).to_string(global_object);
    if (vm.exception())
        return {};
    auto parser = JS::Parser(JS::Lexer(source));
    parser.parse_program();
    return JS::Value(!parser.has_errors());
}

TESTJS_GLOBAL_FUNCTION(run_queued_promise_jobs, runQueuedPromiseJobs)
{
    vm.run_queued_promise_jobs();
    return JS::js_undefined();
}

TESTJS_GLOBAL_FUNCTION(get_weak_set_size, getWeakSetSize)
{
    auto* object = vm.argument(0).to_object(global_object);
    if (!object)
        return {};
    if (!is<JS::WeakSet>(object)) {
        vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WeakSet");
        return {};
    }
    auto* weak_set = static_cast<JS::WeakSet*>(object);
    return JS::Value(weak_set->values().size());
}

TESTJS_GLOBAL_FUNCTION(get_weak_map_size, getWeakMapSize)
{
    auto* object = vm.argument(0).to_object(global_object);
    if (!object)
        return {};
    if (!is<JS::WeakMap>(object)) {
        vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WeakMap");
        return {};
    }
    auto* weak_map = static_cast<JS::WeakMap*>(object);
    return JS::Value(weak_map->values().size());
}

TESTJS_RUN_FILE_FUNCTION(const String& test_file, JS::Interpreter&)
{
    if (!test262_parser_tests)
        return Test::JS::RunFileHookResult::RunAsNormal;

    auto start_time = Test::JS::get_time_in_ms();

    LexicalPath path(test_file);
    auto& dirname = path.dirname();
    enum {
        Early,
        Fail,
        Pass,
        ExplicitPass,
    } expectation { Pass };

    if (dirname.ends_with("early"))
        expectation = Early;
    else if (dirname.ends_with("fail"))
        expectation = Fail;
    else if (dirname.ends_with("pass-explicit"))
        expectation = ExplicitPass;
    else if (dirname.ends_with("pass"))
        expectation = Pass;
    else
        return Test::JS::RunFileHookResult::SkipFile;

    auto parse_result = Test::JS::parse_file(test_file);
    bool test_passed = true;
    String message;
    String expectation_string;

    switch (expectation) {
    case Early:
    case Fail:
        expectation_string = "File should not parse";
        test_passed = parse_result.is_error();
        if (!test_passed)
            message = "Expected the file to fail parsing, but it did not";
        break;
    case Pass:
    case ExplicitPass:
        expectation_string = "File should parse";
        test_passed = !parse_result.is_error();
        if (!test_passed)
            message = "Expected the file to parse, but it did not";
        break;
    }

    auto test_result = test_passed ? Test::Result::Pass : Test::Result::Fail;

    return Test::JS::JSFileResult {
        LexicalPath::relative_path(test_file, Test::JS::g_test_root),
        {},
        Test::JS::get_time_in_ms() - start_time,
        test_result,
        { Test::Suite { "Parse file", test_result, { { expectation_string, test_result, message } } } }
    };
}