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