15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef PPAPI_TESTS_TEST_CASE_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PPAPI_TESTS_TEST_CASE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sstream>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_resource.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_time.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/c/private/ppb_testing_private.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/dev/scrollbar_dev.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/cpp/message_loop.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/view.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_utils.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if (defined __native_client__)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/private/var_private.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestingInstance;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace pp {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace deprecated {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScriptableObject;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Individual classes of tests derive from this generic test case.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCase {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestCase(TestingInstance* instance);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestCase();
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Optionally override to do testcase specific initialization.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default implementation just returns true.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Init();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Override to implement the test case. It will be called after the plugin is
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // first displayed, passing a string. If the string is empty, RunTests should
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // run all tests for this test case. Otherwise, it must be a comma-delimited
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // list of test names, possibly prefixed. E.g.:
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   "Foo_GoodTest,DISABLED_Foo_BadTest,Foo_OtherGoodTest"
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All listed tests which are not prefixed will be run.
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should generally be implemented in a TestCase subclass using the
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // RUN_TEST* macros.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RunTests(const std::string& test_filter) = 0;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeFailureMessage(const char* file, int line,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char* cmd);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !(defined __native_client__)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the scriptable test object for the current test, if any.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Internally, this uses CreateTestObject which each test overrides.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::VarPrivate GetTestObject();
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void ResetTestObject() { test_object_ = pp::VarPrivate(); }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A function that is invoked whenever HandleMessage is called on the
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // associated TestingInstance. Default implementation does nothing.  TestCases
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that want to handle incoming postMessage events should override this
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // method.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void HandleMessage(const pp::Var& message_data);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A function that is invoked whenever DidChangeView is called on the
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // associated TestingInstance. Default implementation does nothing. TestCases
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that want to handle view changes should override this method.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DidChangeView(const pp::View& view);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A function that is invoked whenever HandleInputEvent is called on the
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // associated TestingInstance. Default implementation returns false. TestCases
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that want to handle view changes should override this method.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HandleInputEvent(const pp::InputEvent& event);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void IgnoreLeakedVar(int64_t id);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestingInstance* instance() { return instance_; }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PPB_Testing_Private* testing_interface() { return testing_interface_; }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void QuitMainMessageLoop(PP_Instance instance);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::map<std::string, bool>& remaining_tests() {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return remaining_tests_;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::set<std::string>& skipped_tests() {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return skipped_tests_;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !(defined __native_client__)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden by each test to supply a ScriptableObject corresponding to the
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // test. There can only be one object created for all tests in a given class,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so be sure your object is designed to be re-used.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This object should be created on the heap. Ownership will be passed to the
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // caller. Return NULL if there is no supported test object (the default).
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual pp::deprecated::ScriptableObject* CreateTestObject();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks whether the testing interface is available. Returns true if it is,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // false otherwise. If it is not available, adds a descriptive error. This is
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for use by tests that require the testing interface.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CheckTestingInterface();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes sure the test is run over HTTP.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool EnsureRunningOverHTTP();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns true if |filter| only contains a TestCase name, which normally
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // means "run all tests". Some TestCases require special setup for individual
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // tests, and can use this function to decide whether to ignore those tests.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ShouldRunAllTests(const std::string& filter);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return true if the given test name matches the filter. This is true if
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (a) filter is empty or (b) test_name matches a test name listed in filter
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // exactly.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ShouldRunTest(const std::string& test_name, const std::string& filter);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check for leaked resources and vars at the end of the test. If any exist,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return a string with some information about the error. Otherwise, return
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an empty string.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // You should pass the error string from the test so far; if it is non-empty,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CheckResourcesAndVars will do nothing and return the same string.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string CheckResourcesAndVars(std::string errors);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_TimeTicks NowInTimeTicks();
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the given test method on a background thread and return the result.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T>
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string RunOnThread(std::string(T::*test_to_run)()) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!testing_interface_) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Testing blocking callbacks requires the testing interface. In "
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Chrome, use the --enable-pepper-testing flag.";
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // These tests are only valid if running out-of-process (threading is not
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported in-process). For in-process, just consider it a pass.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!testing_interface_->IsOutOfProcess())
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return std::string();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pp::MessageLoop background_loop(instance_);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ThreadedTestRunner<T> runner(instance_->pp_instance(),
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        static_cast<T*>(this), test_to_run, background_loop);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnThreadInternal(&ThreadedTestRunner<T>::ThreadFunction, &runner,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        testing_interface_);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return runner.result();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pointer to the instance that owns us.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestingInstance* instance_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NULL unless InitTestingInterface is called.
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PPB_Testing_Private* testing_interface_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_callback_type(CallbackType callback_type) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_type_ = callback_type;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallbackType callback_type() const {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return callback_type_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T>
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class ThreadedTestRunner {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef std::string(T::*TestMethodType)();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ThreadedTestRunner(PP_Instance instance,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       T* test_case,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       TestMethodType test_to_run,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       pp::MessageLoop loop)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : instance_(instance),
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_case_(test_case),
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_to_run_(test_to_run),
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          loop_(loop) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& result() { return result_; }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static void ThreadFunction(void* runner) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<ThreadedTestRunner<T>*>(runner)->Run();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Run() {
192bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      int32_t result = loop_.AttachToCurrentThread();
193bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      static_cast<void>(result); // result is not used in the RELEASE build.
194bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      PP_DCHECK(PP_OK == result);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result_ = (test_case_->*test_to_run_)();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Now give the loop a chance to clean up.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loop_.PostQuit(true /* should_destroy */);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loop_.Run();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Tell the main thread to quit its nested message loop, now that the test
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is complete.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestCase::QuitMainMessageLoop(instance_);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result_;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Instance instance_;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    T* test_case_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestMethodType test_to_run_;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pp::MessageLoop loop_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The internals for RunOnThread. This allows us to avoid including
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pp_thread.h in this header file, since it includes system headers like
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // windows.h.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RunOnThreadInternal launches a new thread to run |thread_func|, waits
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for it to complete using RunMessageLoop(), then joins.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunOnThreadInternal(void (*thread_func)(void*),
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           void* thread_param,
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           const PPB_Testing_Private* testing_interface);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void DoQuitMainMessageLoop(void* pp_instance, int32_t result);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Passed when creating completion callbacks in some tests. This determines
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // what kind of callback we use for the test.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallbackType callback_type_;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Var ids that should be ignored when checking for leaks on shutdown.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<int64_t> ignored_leaked_vars_;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // The tests that were found in test_filter. The bool indicates whether the
2302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // test should be run (i.e., it will be false if the test name was prefixed in
2312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // the test_filter string).
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
2332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // This is initialized lazily the first time that ShouldRunTest is called.
2342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::map<std::string, bool> filter_tests_;
2352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Flag indicating whether we have populated filter_tests_ yet.
2362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  bool have_populated_filter_tests_;
2372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // This is initialized with the contents of filter_tests_. As each test is
2382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // run, it is removed from remaining_tests_. When RunTests is finished,
2392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // remaining_tests_ should be empty. Any remaining tests are tests that were
2402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // listed in the test_filter but didn't match any calls to ShouldRunTest,
2412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // meaning it was probably a typo. TestingInstance should log this and
2422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // consider it a failure.
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, bool> remaining_tests_;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If ShouldRunTest is called but the given test name doesn't match anything
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in the test_filter, the test name will be added here. This allows
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TestingInstance to detect when not all tests were listed.
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<std::string> skipped_tests_;
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !(defined __native_client__)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Holds the test object, if any was retrieved from CreateTestObject.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pp::VarPrivate test_object_;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is an implementation detail.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCaseFactory {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef TestCase* (*Method)(TestingInstance* instance);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCaseFactory(const char* name, Method method)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : next_(head_),
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name_(name),
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        method_(method) {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    head_ = this;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class TestingInstance;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCaseFactory* next_;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name_;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Method method_;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TestCaseFactory* head_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace internal {
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The internal namespace contains implementation details that are used by
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the ASSERT macros.
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This base class provides a ToString that works for classes that can be
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// converted to a string using std::stringstream. Later, we'll do
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// specializations for types that we know will work with this approach.
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class T>
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct StringinatorBase {
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static std::string ToString(const T& value) {
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::stringstream stream;
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    stream << value;
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return stream.str();
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Not implemented, do not use.
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note, these are protected because Windows complains if I make these private
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // and then inherit StringinatorBase (even though they're never used).
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StringinatorBase();
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~StringinatorBase();
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This default class template is for types that we don't recognize as
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// something we can convert into a string using stringstream. Types that we
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// know *can* be turned to a string should have specializations below.
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class T>
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct Stringinator {
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static std::string ToString(const T& value) {
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::string();
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Not implemented, do not use.
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Stringinator();
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~Stringinator();
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Define some full specializations for types that can just use stringstream.
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define DEFINE_STRINGINATOR_FOR_TYPE(type) \
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <> \
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct Stringinator<type> : public StringinatorBase<type> {};
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(int32_t);
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(uint32_t);
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(int64_t);
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(uint64_t);
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(float);
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(double);
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(bool);
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_STRINGINATOR_FOR_TYPE(std::string);
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#undef DEFINE_STRINGINATOR_FOR_TYPE
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class T>
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ToString(const T& param) {
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return Stringinator<T>::ToString(param);
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This overload is necessary to allow enum values (such as those from
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// pp_errors.h, including PP_OK) to work. They won't automatically convert to
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// an integral type to instantiate the above function template.
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)inline std::string ToString(int32_t param) {
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return Stringinator<int32_t>::ToString(param);
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)inline std::string ToString(const char* c_string) {
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return std::string(c_string);
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This overload deals with pointers.
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class T>
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ToString(const T* ptr) {
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uintptr_t ptr_val = reinterpret_cast<uintptr_t>(ptr);
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::stringstream stream;
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stream << ptr_val;
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return stream.str();
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ComparisonHelper classes wrap the left-hand parameter of a binary comparison
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ASSERT. The correct class gets chosen based on whether or not it's a NULL or
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 0 literal. If it is a NULL/0 literal, we use NullLiteralComparisonHelper.
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// For all other parameters, we use ComparisonHelper. There's also a
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// specialization of ComparisonHelper for int below (see below for why
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that is.)
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ComparisonHelper does two things for the left param:
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//  1) Provides all the appropriate CompareXX functions (CompareEQ, etc).
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//  2) Provides ToString.
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class T>
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct ComparisonHelper {
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit ComparisonHelper(const T& param) : value(param) {}
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareEQ(const U& right) const {
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return value == right;
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareNE(const U& right) const {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return value != right;
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareLT(const U& right) const {
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return value < right;
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareGT(const U& right) const {
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return value > right;
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareLE(const U& right) const {
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return value <= right;
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareGE(const U& right) const {
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return value >= right;
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string ToString() const {
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return internal::ToString(value);
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const T& value;
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Used for NULL or 0.
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct NullLiteralComparisonHelper {
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NullLiteralComparisonHelper() : value(0) {}
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareEQ(const U& right) const {
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0 == right;
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareNE(const U& right) const {
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0 != right;
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareLT(const U& right) const {
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0 < right;
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareGT(const U& right) const {
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0 > right;
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareLE(const U& right) const {
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0 <= right;
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareGE(const U& right) const {
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0 >= right;
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string ToString() const {
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::string("0");
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int value;
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This class makes it safe to use an integer literal (like 5, or 123) when
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// comparing with an unsigned. For example:
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ASSERT_EQ(1, some_vector.size());
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// We do a lot of those comparisons, so this makes it easy to get it right
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// (rather than forcing assertions to use unsigned literals like 5u or 123u).
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is slightly risky; we're static_casting an int to whatever's on the
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// right. If the left value is negative and the right hand side is a large
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// unsigned value, it's possible that the comparison will succeed when maybe
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// it shouldn't have.
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(dmichael): It should be possible to fix this and upgrade int32_t and
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//                 uint32_t to int64_t for the comparison, and make any unsafe
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//                 comparisons into compile errors.
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <>
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct ComparisonHelper<int> {
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit ComparisonHelper(int param) : value(param) {}
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareEQ(const U& right) const {
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return static_cast<U>(value) == right;
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareNE(const U& right) const {
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return static_cast<U>(value) != right;
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareLT(const U& right) const {
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return static_cast<U>(value) < right;
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareGT(const U& right) const {
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return static_cast<U>(value) > right;
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareLE(const U& right) const {
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return static_cast<U>(value) <= right;
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class U>
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool CompareGE(const U& right) const {
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return static_cast<U>(value) >= right;
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string ToString() const {
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return internal::ToString(value);
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int value;
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The default is for the case there the parameter is *not* a NULL or 0 literal.
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <bool is_null_literal>
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct ParameterWrapper {
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  template <class T>
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static ComparisonHelper<T> WrapValue(const T& value) {
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return ComparisonHelper<T>(value);
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This overload is so that we can deal with values from anonymous enums,
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // like the one in pp_errors.h. The function template above won't be
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // considered a match by the compiler.
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static ComparisonHelper<int> WrapValue(int value) {
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return ComparisonHelper<int>(value);
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The parameter to WrapValue *is* a NULL or 0 literal.
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <>
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct ParameterWrapper<true> {
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We just use "..." and ignore the parameter. This sidesteps some problems we
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // would run in to (not all compilers have the same set of constraints).
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // - We can't use a pointer type, because int and enums won't convert.
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // - We can't use an integral type, because pointers won't convert.
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // - We can't overload, because it will sometimes be ambiguous.
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // - We can't templatize and deduce the parameter. Some compilers will deduce
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //   int for NULL, and then refuse to convert NULL to an int.
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We know in this case that the value is 0, so there's no need to capture the
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // value. We also know it's a fundamental type, so it's safe to pass to "...".
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // (It's illegal to pass non-POD types to ...).
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static NullLiteralComparisonHelper WrapValue(...) {
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NullLiteralComparisonHelper();
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// IS_NULL_LITERAL(type) is a little template metaprogramming for determining
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// if a type is a null or zero literal (NULL or 0 or a constant that evaluates
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// to one of those).
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The idea is that for NULL or 0, any pointer type is always a better match
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// than "...". But no other pointer types or literals should convert
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// automatically to InternalDummyClass.
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct InternalDummyClass {};
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)char TestNullLiteral(const InternalDummyClass*);
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct BiggerThanChar { char dummy[2]; };
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BiggerThanChar TestNullLiteral(...);
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// If the compiler chooses the overload of TestNullLiteral which returns char,
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// then we know the value converts automatically to InternalDummyClass*, which
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// should only be true of NULL and 0 constants.
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define IS_NULL_LITERAL(a) sizeof(internal::TestNullLiteral(a)) == sizeof(char)
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class T, class U>
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static std::string MakeBinaryComparisonFailureMessage(
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* comparator,
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const T& left,
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const U& right,
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* left_precompiler_string,
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* right_precompiler_string,
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* file_name,
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int line_number) {
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string error_msg =
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string("Failed ASSERT_") + comparator + "(" +
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      left_precompiler_string + ", " + right_precompiler_string + ")";
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string left_string(left.ToString());
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string right_string(ToString(right));
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!left_string.empty())
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    error_msg += " Left: (" + left_string + ")";
5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!right_string.empty())
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    error_msg += " Right: (" + right_string + ")";
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return TestCase::MakeFailureMessage(file_name, line_number,
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      error_msg.c_str());
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The Comparison function templates allow us to pass the parameter for
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ASSERT macros below and have them be evaluated only once. This is important
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// for cases where the parameter might be an expression with side-effects, like
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// a function call.
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define DEFINE_COMPARE_FUNCTION(comparator_name) \
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <class T, class U> \
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string Compare ## comparator_name ( \
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const T& left, \
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const U& right, \
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* left_precompiler_string, \
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* right_precompiler_string, \
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* file_name, \
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int line_num) { \
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!(left.Compare##comparator_name(right))) { \
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MakeBinaryComparisonFailureMessage(#comparator_name, \
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              left, \
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              right, \
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              left_precompiler_string, \
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              right_precompiler_string, \
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              file_name, \
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              line_num); \
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } \
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return std::string(); \
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_COMPARE_FUNCTION(EQ)
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_COMPARE_FUNCTION(NE)
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_COMPARE_FUNCTION(LT)
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_COMPARE_FUNCTION(LE)
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_COMPARE_FUNCTION(GT)
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DEFINE_COMPARE_FUNCTION(GE)
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#undef DEFINE_COMPARE_FUNCTION
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)inline std::string CompareDoubleEq(ComparisonHelper<double> left,
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   double right,
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   const char* left_precompiler_string,
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   const char* right_precompiler_string,
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   const char* file_name,
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   int linu_num) {
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!(std::fabs(left.value - right) <=
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        std::numeric_limits<double>::epsilon())) {
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MakeBinaryComparisonFailureMessage(
5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "~=", left, right, left_precompiler_string, right_precompiler_string,
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        __FILE__, __LINE__);
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return std::string();
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace internal
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use the REGISTER_TEST_CASE macro in your TestCase implementation file to
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// register your TestCase.  If your test is named TestFoo, then add the
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// following to test_foo.cc:
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   REGISTER_TEST_CASE(Foo);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will cause your test to be included in the set of known tests.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REGISTER_TEST_CASE(name)                                            \
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TestCase* Test##name##_FactoryMethod(TestingInstance* instance) {  \
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new Test##name(instance);                                        \
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }                                                                         \
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TestCaseFactory g_Test##name_factory(                              \
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    #name, &Test##name##_FactoryMethod                                      \
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  )
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macro for calling functions implementing specific tests in the
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RunTest function. This assumes the function name is TestFoo where Foo is the
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// test |name|.
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RUN_TEST(name, test_filter) \
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldRunTest(#name, test_filter)) { \
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_callback_type(PP_OPTIONAL); \
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_TimeTicks start_time(NowInTimeTicks()); \
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    instance_->LogTest(#name, \
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       CheckResourcesAndVars(Test##name()), \
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       start_time); \
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Like RUN_TEST above but forces functions taking callbacks to complete
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// asynchronously on success or error.
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RUN_TEST_FORCEASYNC(name, test_filter) \
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldRunTest(#name, test_filter)) { \
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_callback_type(PP_REQUIRED); \
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_TimeTicks start_time(NowInTimeTicks()); \
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instance_->LogTest(#name"ForceAsync", \
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       CheckResourcesAndVars(Test##name()), \
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       start_time); \
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RUN_TEST_BLOCKING(test_case, name, test_filter) \
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldRunTest(#name, test_filter)) { \
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_callback_type(PP_BLOCKING); \
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_TimeTicks start_time(NowInTimeTicks()); \
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    instance_->LogTest( \
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        #name"Blocking", \
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CheckResourcesAndVars(RunOnThread(&test_case::Test##name)), \
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        start_time); \
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RUN_TEST_BACKGROUND(test_case, name, test_filter) \
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldRunTest(#name, test_filter)) { \
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_TimeTicks start_time(NowInTimeTicks()); \
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    instance_->LogTest( \
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        #name"Background", \
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CheckResourcesAndVars(RunOnThread(&test_case::Test##name)), \
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        start_time); \
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RUN_TEST_FORCEASYNC_AND_NOT(name, test_filter) \
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUN_TEST_FORCEASYNC(name, test_filter); \
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUN_TEST(name, test_filter); \
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Run a test with all possible callback types.
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RUN_CALLBACK_TEST(test_case, name, test_filter) \
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUN_TEST_FORCEASYNC(name, test_filter); \
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUN_TEST(name, test_filter); \
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUN_TEST_BLOCKING(test_case, name, test_filter); \
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RUN_TEST_BACKGROUND(test_case, name, test_filter); \
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define RUN_TEST_WITH_REFERENCE_CHECK(name, test_filter) \
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ShouldRunTest(#name, test_filter)) { \
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_callback_type(PP_OPTIONAL); \
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t objects = testing_interface_->GetLiveObjectsForInstance( \
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instance_->pp_instance()); \
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string error_message = Test##name(); \
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (error_message.empty() && \
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        testing_interface_->GetLiveObjectsForInstance( \
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            instance_->pp_instance()) != objects) \
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_message = MakeFailureMessage(__FILE__, __LINE__, \
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "reference leak check"); \
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PP_TimeTicks start_time(NowInTimeTicks()); \
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    instance_->LogTest(#name, \
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       CheckResourcesAndVars(error_message), \
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       start_time); \
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(dmichael): Add CheckResourcesAndVars above when Windows tests pass
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                 cleanly. crbug.com/173503
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper macros for checking values in tests, and returning a location
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// description of the test fails.
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_TRUE(cmd) \
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  do { \
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!(cmd)) \
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return MakeFailureMessage(__FILE__, __LINE__, #cmd); \
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } while (false)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_FALSE(cmd) ASSERT_TRUE(!(cmd))
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define COMPARE_BINARY_INTERNAL(comparison_type, a, b) \
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    internal::Compare##comparison_type( \
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        internal::ParameterWrapper<IS_NULL_LITERAL(a)>::WrapValue(a), \
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        (b), \
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        #a, \
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        #b, \
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        __FILE__, \
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        __LINE__)
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_BINARY_INTERNAL(comparison_type, a, b) \
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)do { \
7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string internal_assert_result_string = \
7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      COMPARE_BINARY_INTERNAL(comparison_type, a, b); \
7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!internal_assert_result_string.empty()) { \
7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return internal_assert_result_string; \
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } \
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} while(false)
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_EQ(a, b) ASSERT_BINARY_INTERNAL(EQ, a, b)
7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_NE(a, b) ASSERT_BINARY_INTERNAL(NE, a, b)
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_LT(a, b) ASSERT_BINARY_INTERNAL(LT, a, b)
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_LE(a, b) ASSERT_BINARY_INTERNAL(LE, a, b)
7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_GT(a, b) ASSERT_BINARY_INTERNAL(GT, a, b)
7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_GE(a, b) ASSERT_BINARY_INTERNAL(GE, a, b)
7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ASSERT_DOUBLE_EQ(a, b) \
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)do { \
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string internal_assert_result_string = \
7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      internal::CompareDoubleEq( \
7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          internal::ParameterWrapper<IS_NULL_LITERAL(a)>::WrapValue(a), \
7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          (b), \
7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          #a, \
7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          #b, \
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          __FILE__, \
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          __LINE__); \
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!internal_assert_result_string.empty()) { \
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return internal_assert_result_string; \
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } \
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} while(false)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Runs |function| as a subtest and asserts that it has passed.
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASSERT_SUBTEST_SUCCESS(function) \
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result = (function); \
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!result.empty()) \
7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return TestCase::MakeFailureMessage(__FILE__, __LINE__, result.c_str()); \
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (false)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PASS() return std::string()
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // PPAPI_TESTS_TEST_CASE_H_
745