Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  testErrorInterceptor.cpp   Sprache: C

 
#include <iterator>

#include "js/ErrorInterceptor.h"
#include "jsapi-tests/tests.h"
#include "util/StringBuilder.h"

// Tests for JS_GetErrorInterceptorCallback and JS_SetErrorInterceptorCallback.

namespace {
MOZ_RUNINIT static JS::PersistentRootedString gLatestMessage;

// An interceptor that stores the error in `gLatestMessage`.
struct SimpleInterceptor : JSErrorInterceptor {
  virtual void interceptError(JSContext* cx, JS::HandleValue val) override {
    js::JSStringBuilder buffer(cx);
    if (!ValueToStringBuilder(cx, val, buffer)) {
      MOZ_CRASH("Could not convert to string buffer");
    }
    gLatestMessage = buffer.finishString();
    if (!gLatestMessage) {
      MOZ_CRASH("Could not convert to string");
    }
  }
};

bool equalStrings(JSContext* cx, JSString* a, JSString* b) {
  int32_t result = 0;
  if (!JS_CompareStrings(cx, a, b, &result)) {
    MOZ_CRASH("Could not compare strings");
  }
  return result == 0;
}
}  // namespace

BEGIN_TEST(testErrorInterceptor) {
  // Run the following snippets.
  const char* SAMPLES[] = {
      "throw new Error('I am an Error')\0",
      "throw new TypeError('I am a TypeError')\0",
      "throw new ReferenceError('I am a ReferenceError')\0",
      "throw new SyntaxError('I am a SyntaxError')\0",
      "throw 5\0",
      "foo[0]\0",
      "b[\0",
  };
  // With the simpleInterceptor, we should end up with the following error:
  const char* TO_STRING[] = {
      "Error: I am an Error\0",
      "TypeError: I am a TypeError\0",
      "ReferenceError: I am a ReferenceError\0",
      "SyntaxError: I am a SyntaxError\0",
      "5\0",
      "ReferenceError: foo is not defined\0",
      "SyntaxError: expected expression, got end of script\0",
  };
  static_assert(std::size(SAMPLES) == std::size(TO_STRING));

  // Save original callback.
  JSErrorInterceptor* original = JS_GetErrorInterceptorCallback(cx->runtime());
  gLatestMessage.init(cx);

  // Test without callback.
  JS_SetErrorInterceptorCallback(cx->runtime(), nullptr);
  CHECK(gLatestMessage == nullptr);

  for (auto sample : SAMPLES) {
    if (execDontReport(sample, __FILE__, __LINE__)) {
      MOZ_CRASH("This sample should have failed");
    }
    CHECK(JS_IsExceptionPending(cx));
    CHECK(gLatestMessage == nullptr);
    JS_ClearPendingException(cx);
  }

  // Test with callback.
  SimpleInterceptor simpleInterceptor;
  JS_SetErrorInterceptorCallback(cx->runtime(), &simpleInterceptor);

  // Test that we return the right callback.
  CHECK_EQUAL(JS_GetErrorInterceptorCallback(cx->runtime()),
              &simpleInterceptor);

  // This shouldn't cause any error.
  EXEC("function bar() {}");
  CHECK(gLatestMessage == nullptr);

  // Test error throwing with a callback that succeeds.
  for (size_t i = 0; i < std::size(SAMPLES); ++i) {
    // This should cause the appropriate error.
    if (execDontReport(SAMPLES[i], __FILE__, __LINE__)) {
      MOZ_CRASH("This sample should have failed");
    }
    CHECK(JS_IsExceptionPending(cx));

    // Check result of callback.
    CHECK(gLatestMessage != nullptr);
    CHECK(js::StringEqualsAscii(&gLatestMessage->asLinear(), TO_STRING[i]));

    // Check the final error.
    JS::RootedValue exn(cx);
    CHECK(JS_GetPendingException(cx, &exn));
    JS_ClearPendingException(cx);

    js::JSStringBuilder buffer(cx);
    CHECK(ValueToStringBuilder(cx, exn, buffer));
    JS::Rooted<JSLinearString*> linear(cx, buffer.finishString());
    CHECK(equalStrings(cx, linear, gLatestMessage));

    // Cleanup.
    gLatestMessage = nullptr;
  }

  // Test again without callback.
  JS_SetErrorInterceptorCallback(cx->runtime(), nullptr);
  for (size_t i = 0; i < std::size(SAMPLES); ++i) {
    if (execDontReport(SAMPLES[i], __FILE__, __LINE__)) {
      MOZ_CRASH("This sample should have failed");
    }
    CHECK(JS_IsExceptionPending(cx));

    // Check that the callback wasn't called.
    CHECK(gLatestMessage == nullptr);

    // Check the final error.
    JS::RootedValue exn(cx);
    CHECK(JS_GetPendingException(cx, &exn));
    JS_ClearPendingException(cx);

    js::JSStringBuilder buffer(cx);
    CHECK(ValueToStringBuilder(cx, exn, buffer));
    JS::Rooted<JSLinearString*> linear(cx, buffer.finishString());
    CHECK(js::StringEqualsAscii(linear, TO_STRING[i]));

    // Cleanup.
    gLatestMessage = nullptr;
  }

  // Cleanup
  JS_SetErrorInterceptorCallback(cx->runtime(), original);
  gLatestMessage = nullptr;
  JS_ClearPendingException(cx);

  return true;
}
END_TEST(testErrorInterceptor)

74%


¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge