Просмотр исходного кода

LibTest: Add --json flag to JS test runner

This will not show the colorful human-readable file results and final
test results summary but instead output a JSON blob containing all test
information, which can then be processed by other programs easily.
Linus Groh 4 лет назад
Родитель
Сommit
1828607606

+ 37 - 3
Userland/Libraries/LibTest/JavaScriptTestRunner.h

@@ -148,11 +148,12 @@ public:
         return s_the;
         return s_the;
     }
     }
 
 
-    TestRunner(String test_root, String common_path, bool print_times, bool print_progress)
+    TestRunner(String test_root, String common_path, bool print_times, bool print_progress, bool print_json)
         : m_common_path(move(common_path))
         : m_common_path(move(common_path))
         , m_test_root(move(test_root))
         , m_test_root(move(test_root))
         , m_print_times(print_times)
         , m_print_times(print_times)
         , m_print_progress(print_progress)
         , m_print_progress(print_progress)
+        , m_print_json(print_json)
     {
     {
         VERIFY(!s_the);
         VERIFY(!s_the);
         s_the = this;
         s_the = this;
@@ -174,11 +175,13 @@ protected:
     virtual JSFileResult run_file_test(const String& test_path);
     virtual JSFileResult run_file_test(const String& test_path);
     void print_file_result(const JSFileResult& file_result) const;
     void print_file_result(const JSFileResult& file_result) const;
     void print_test_results() const;
     void print_test_results() const;
+    void print_test_results_as_json() const;
 
 
     String m_common_path;
     String m_common_path;
     String m_test_root;
     String m_test_root;
     bool m_print_times;
     bool m_print_times;
     bool m_print_progress;
     bool m_print_progress;
+    bool m_print_json;
 
 
     double m_total_elapsed_time_in_ms { 0 };
     double m_total_elapsed_time_in_ms { 0 };
     Test::Counts m_counts;
     Test::Counts m_counts;
@@ -271,7 +274,9 @@ inline void TestRunner::run()
         if (!path.matches(g_test_glob))
         if (!path.matches(g_test_glob))
             continue;
             continue;
         ++progress_counter;
         ++progress_counter;
-        print_file_result(run_file_test(path));
+        auto file_result = run_file_test(path);
+        if (!m_print_json)
+            print_file_result(file_result);
         if (m_print_progress)
         if (m_print_progress)
             warn("\033]9;{};{};\033\\", progress_counter, test_paths.size());
             warn("\033]9;{};{};\033\\", progress_counter, test_paths.size());
     }
     }
@@ -279,7 +284,10 @@ inline void TestRunner::run()
     if (m_print_progress)
     if (m_print_progress)
         warn("\033]9;-1;\033\\");
         warn("\033]9;-1;\033\\");
 
 
-    print_test_results();
+    if (!m_print_json)
+        print_test_results();
+    else
+        print_test_results_as_json();
 }
 }
 
 
 inline AK::Result<NonnullRefPtr<JS::Program>, ParserError> parse_file(const String& file_path)
 inline AK::Result<NonnullRefPtr<JS::Program>, ParserError> parse_file(const String& file_path)
@@ -662,4 +670,30 @@ inline void TestRunner::print_test_results() const
     }
     }
     outln();
     outln();
 }
 }
+
+inline void TestRunner::print_test_results_as_json() const
+{
+    JsonObject suites;
+    suites.set("failed", m_counts.suites_failed);
+    suites.set("passed", m_counts.suites_passed);
+    suites.set("total", m_counts.suites_failed + m_counts.suites_passed);
+
+    JsonObject tests;
+    tests.set("failed", m_counts.tests_failed);
+    tests.set("passed", m_counts.tests_passed);
+    tests.set("skipped", m_counts.tests_skipped);
+    tests.set("total", m_counts.tests_failed + m_counts.tests_passed + m_counts.tests_skipped);
+
+    JsonObject results;
+    results.set("suites", suites);
+    results.set("tests", tests);
+
+    JsonObject root;
+    root.set("results", results);
+    root.set("files_total", m_counts.files_total);
+    root.set("duration", m_total_elapsed_time_in_ms / 1000.0);
+
+    outln("{}", root.to_string());
+}
+
 }
 }

+ 3 - 1
Userland/Libraries/LibTest/JavaScriptTestRunnerMain.cpp

@@ -80,6 +80,7 @@ int main(int argc, char** argv)
 #else
 #else
         false;
         false;
 #endif
 #endif
+    bool print_json = false;
     const char* specified_test_root = nullptr;
     const char* specified_test_root = nullptr;
     String common_path;
     String common_path;
 
 
@@ -100,6 +101,7 @@ int main(int argc, char** argv)
             return true;
             return true;
         },
         },
     });
     });
+    args_parser.add_option(print_json, "Show results as JSON", "json", 'j');
     args_parser.add_option(g_collect_on_every_allocation, "Collect garbage after every allocation", "collect-often", 'g');
     args_parser.add_option(g_collect_on_every_allocation, "Collect garbage after every allocation", "collect-often", 'g');
     args_parser.add_option(g_test_glob, "Only run tests matching the given glob", "filter", 'f', "glob");
     args_parser.add_option(g_test_glob, "Only run tests matching the given glob", "filter", 'f', "glob");
     for (auto& entry : g_extra_args)
     for (auto& entry : g_extra_args)
@@ -164,7 +166,7 @@ int main(int argc, char** argv)
     if (!g_vm)
     if (!g_vm)
         g_vm = JS::VM::create();
         g_vm = JS::VM::create();
 
 
-    TestRunner test_runner(test_root, common_path, print_times, print_progress);
+    TestRunner test_runner(test_root, common_path, print_times, print_progress, print_json);
     test_runner.run();
     test_runner.run();
 
 
     g_vm = nullptr;
     g_vm = nullptr;