OLD | NEW |
| (Empty) |
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): Fix no-compile tests (which are all disabled; crbug.com/105388) | |
9 // and write some "negative" tests. | |
10 | |
11 #include "mojo/public/cpp/system/macros.h" | |
12 | |
13 #include <assert.h> | |
14 #include <stdint.h> | |
15 #include <stdlib.h> | |
16 | |
17 #include "gtest/gtest.h" | |
18 | |
19 namespace mojo { | |
20 namespace { | |
21 | |
22 // Note: MSVS is very strict (and arguably buggy) about warnings for classes | |
23 // defined in a local scope, so define these globally. | |
24 struct TestOverrideBaseClass { | |
25 virtual ~TestOverrideBaseClass() {} | |
26 virtual void ToBeOverridden() {} | |
27 virtual void AlsoToBeOverridden() = 0; | |
28 }; | |
29 | |
30 struct TestOverrideSubclass : public TestOverrideBaseClass { | |
31 ~TestOverrideSubclass() override {} | |
32 void ToBeOverridden() override {} | |
33 void AlsoToBeOverridden() override {} | |
34 }; | |
35 | |
36 TEST(MacrosTest, Override) { | |
37 TestOverrideSubclass x; | |
38 x.ToBeOverridden(); | |
39 x.AlsoToBeOverridden(); | |
40 } | |
41 | |
42 // Note: MSVS is very strict (and arguably buggy) about warnings for classes | |
43 // defined in a local scope, so define these globally. | |
44 class TestDisallowCopyAndAssignClass { | |
45 public: | |
46 TestDisallowCopyAndAssignClass() {} | |
47 explicit TestDisallowCopyAndAssignClass(int) {} | |
48 void NoOp() {} | |
49 | |
50 private: | |
51 MOJO_DISALLOW_COPY_AND_ASSIGN(TestDisallowCopyAndAssignClass); | |
52 }; | |
53 | |
54 TEST(MacrosTest, DisallowCopyAndAssign) { | |
55 TestDisallowCopyAndAssignClass x; | |
56 x.NoOp(); | |
57 TestDisallowCopyAndAssignClass y(789); | |
58 y.NoOp(); | |
59 } | |
60 | |
61 // Test that |MOJO_ARRAYSIZE()| works in a |static_assert()|. | |
62 const int kGlobalArray[5] = {1, 2, 3, 4, 5}; | |
63 static_assert(MOJO_ARRAYSIZE(kGlobalArray) == 5u, | |
64 "MOJO_ARRAY_SIZE() failed in static_assert()"); | |
65 | |
66 TEST(MacrosTest, ArraySize) { | |
67 double local_array[4] = {6.7, 7.8, 8.9, 9.0}; | |
68 // MSVS considers this local variable unused since MOJO_ARRAYSIZE only takes | |
69 // the size of the type of the local and not the values itself. | |
70 MOJO_ALLOW_UNUSED_LOCAL(local_array); | |
71 EXPECT_EQ(4u, MOJO_ARRAYSIZE(local_array)); | |
72 | |
73 // Prevent gcc unneeded-internal-declaration warning. | |
74 MOJO_ALLOW_UNUSED_LOCAL(kGlobalArray); | |
75 } | |
76 | |
77 // Note: MSVS is very strict (and arguably buggy) about warnings for classes | |
78 // defined in a local scope, so define these globally. | |
79 class MoveOnlyInt { | |
80 public: | |
81 MoveOnlyInt() : is_set_(false), value_() {} | |
82 explicit MoveOnlyInt(int value) : is_set_(true), value_(value) {} | |
83 ~MoveOnlyInt() {} | |
84 | |
85 // Move-only constructor and operator=. | |
86 MoveOnlyInt(MoveOnlyInt&& other) { *this = other.Pass(); } | |
87 MoveOnlyInt& operator=(MoveOnlyInt&& other) { | |
88 if (&other != this) { | |
89 is_set_ = other.is_set_; | |
90 value_ = other.value_; | |
91 other.is_set_ = false; | |
92 } | |
93 return *this; | |
94 } | |
95 | |
96 int value() const { | |
97 assert(is_set()); | |
98 return value_; | |
99 } | |
100 bool is_set() const { return is_set_; } | |
101 | |
102 private: | |
103 bool is_set_; | |
104 int value_; | |
105 | |
106 MOJO_MOVE_ONLY_TYPE(MoveOnlyInt); | |
107 }; | |
108 | |
109 TEST(MacrosTest, MoveOnlyType) { | |
110 MoveOnlyInt x(123); | |
111 EXPECT_TRUE(x.is_set()); | |
112 EXPECT_EQ(123, x.value()); | |
113 MoveOnlyInt y; | |
114 EXPECT_FALSE(y.is_set()); | |
115 y = x.Pass(); | |
116 EXPECT_FALSE(x.is_set()); | |
117 EXPECT_TRUE(y.is_set()); | |
118 EXPECT_EQ(123, y.value()); | |
119 MoveOnlyInt z(y.Pass()); | |
120 EXPECT_FALSE(y.is_set()); | |
121 EXPECT_TRUE(z.is_set()); | |
122 EXPECT_EQ(123, z.value()); | |
123 z = z.Pass(); | |
124 EXPECT_TRUE(z.is_set()); | |
125 EXPECT_EQ(123, z.value()); | |
126 } | |
127 | |
128 // The test for |ignore_result()| is also just a compilation test. (Note that | |
129 // |MOJO_WARN_UNUSED_RESULT| can only be used in the prototype. | |
130 int ReturnsIntYouMustUse() MOJO_WARN_UNUSED_RESULT; | |
131 | |
132 int ReturnsIntYouMustUse() { | |
133 return 123; | |
134 } | |
135 | |
136 TEST(MacrosTest, IgnoreResult) { | |
137 ignore_result(ReturnsIntYouMustUse()); | |
138 } | |
139 | |
140 } // namespace | |
141 } // namespace mojo | |
OLD | NEW |