Home | History | Annotate | Download | only in tests
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // This file tests the C++ Mojo system macros and consists of "positive" tests,
      6 // i.e., those verifying that things work (without compile errors, or even
      7 // warnings if warnings are treated as errors).
      8 // TODO(vtl): Maybe rename "MacrosCppTest" -> "MacrosTest" if/when this gets
      9 // compiled into a different binary from the C API tests.
     10 // TODO(vtl): Fix no-compile tests (which are all disabled; crbug.com/105388)
     11 // and write some "negative" tests.
     12 
     13 #include "mojo/public/cpp/system/macros.h"
     14 
     15 #include <assert.h>
     16 #include <stdint.h>
     17 #include <stdlib.h>
     18 
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace mojo {
     22 namespace {
     23 
     24 // Note: MSVS is very strict (and arguably buggy) about warnings for classes
     25 // defined in a local scope, so define these globally.
     26 struct TestOverrideBaseClass {
     27   virtual ~TestOverrideBaseClass() {}
     28   virtual void ToBeOverridden() {}
     29   virtual void AlsoToBeOverridden() = 0;
     30 };
     31 
     32 struct TestOverrideSubclass : public TestOverrideBaseClass {
     33   virtual ~TestOverrideSubclass() {}
     34   virtual void ToBeOverridden() MOJO_OVERRIDE {}
     35   virtual void AlsoToBeOverridden() MOJO_OVERRIDE {}
     36 };
     37 
     38 TEST(MacrosCppTest, Override) {
     39   TestOverrideSubclass x;
     40   x.ToBeOverridden();
     41   x.AlsoToBeOverridden();
     42 }
     43 
     44 // Note: MSVS is very strict (and arguably buggy) about warnings for classes
     45 // defined in a local scope, so define these globally.
     46 class TestDisallowCopyAndAssignClass {
     47  public:
     48   TestDisallowCopyAndAssignClass() {}
     49   explicit TestDisallowCopyAndAssignClass(int) {}
     50   void NoOp() {}
     51 
     52  private:
     53   MOJO_DISALLOW_COPY_AND_ASSIGN(TestDisallowCopyAndAssignClass);
     54 };
     55 
     56 TEST(MacrosCppTest, DisallowCopyAndAssign) {
     57   TestDisallowCopyAndAssignClass x;
     58   x.NoOp();
     59   TestDisallowCopyAndAssignClass y(789);
     60   y.NoOp();
     61 }
     62 
     63 // Test that |MOJO_ARRAYSIZE()| works in a |MOJO_COMPILE_ASSERT()|.
     64 const int kGlobalArray[5] = { 1, 2, 3, 4, 5 };
     65 MOJO_COMPILE_ASSERT(MOJO_ARRAYSIZE(kGlobalArray) == 5u,
     66                     mojo_array_size_failed_in_compile_assert);
     67 
     68 TEST(MacrosCppTest, ArraySize) {
     69   double local_array[4] = { 6.7, 7.8, 8.9, 9.0 };
     70   EXPECT_EQ(4u, MOJO_ARRAYSIZE(local_array));
     71 }
     72 
     73 // Note: MSVS is very strict (and arguably buggy) about warnings for classes
     74 // defined in a local scope, so define these globally.
     75 class MoveOnlyInt {
     76   MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(MoveOnlyInt, RValue)
     77 
     78  public:
     79   MoveOnlyInt() : is_set_(false), value_() {}
     80   explicit MoveOnlyInt(int value) : is_set_(true), value_(value) {}
     81   ~MoveOnlyInt() {}
     82 
     83   // Move-only constructor and operator=.
     84   MoveOnlyInt(RValue other) { *this = other; }
     85   MoveOnlyInt& operator=(RValue other) {
     86     if (other.object != this) {
     87       is_set_ = other.object->is_set_;
     88       value_ = other.object->value_;
     89       other.object->is_set_ = false;
     90     }
     91     return *this;
     92   }
     93 
     94   int value() const {
     95     assert(is_set());
     96     return value_;
     97   }
     98   bool is_set() const { return is_set_; }
     99 
    100  private:
    101   bool is_set_;
    102   int value_;
    103 };
    104 
    105 TEST(MacrosCppTest, MoveOnlyTypeForCpp03) {
    106   MoveOnlyInt x(123);
    107   EXPECT_TRUE(x.is_set());
    108   EXPECT_EQ(123, x.value());
    109   MoveOnlyInt y;
    110   EXPECT_FALSE(y.is_set());
    111   y = x.Pass();
    112   EXPECT_FALSE(x.is_set());
    113   EXPECT_TRUE(y.is_set());
    114   EXPECT_EQ(123, y.value());
    115   MoveOnlyInt z(y.Pass());
    116   EXPECT_FALSE(y.is_set());
    117   EXPECT_TRUE(z.is_set());
    118   EXPECT_EQ(123, z.value());
    119   z = z.Pass();
    120   EXPECT_TRUE(z.is_set());
    121   EXPECT_EQ(123, z.value());
    122 }
    123 
    124 }  // namespace
    125 }  // namespace mojo
    126