blob: 60eb553badc433d85bb4297fc21b8f07edc64299 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file tests the C++ Mojo system macros and consists of "positive" tests,
// i.e., those verifying that things work (without compile errors, or even
// warnings if warnings are treated as errors).
// TODO(vtl): Fix no-compile tests (which are all disabled; crbug.com/105388)
// and write some "negative" tests.
#include "mojo/public/cpp/system/macros.h"
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "gtest/gtest.h"
namespace mojo {
namespace {
// Note: MSVS is very strict (and arguably buggy) about warnings for classes
// defined in a local scope, so define these globally.
struct TestOverrideBaseClass {
virtual ~TestOverrideBaseClass() {}
virtual void ToBeOverridden() {}
virtual void AlsoToBeOverridden() = 0;
};
struct TestOverrideSubclass : public TestOverrideBaseClass {
~TestOverrideSubclass() override {}
void ToBeOverridden() override {}
void AlsoToBeOverridden() override {}
};
TEST(MacrosTest, Override) {
TestOverrideSubclass x;
x.ToBeOverridden();
x.AlsoToBeOverridden();
}
// Note: MSVS is very strict (and arguably buggy) about warnings for classes
// defined in a local scope, so define these globally.
class TestDisallowCopyAndAssignClass {
public:
TestDisallowCopyAndAssignClass() {}
explicit TestDisallowCopyAndAssignClass(int) {}
void NoOp() {}
private:
MOJO_DISALLOW_COPY_AND_ASSIGN(TestDisallowCopyAndAssignClass);
};
TEST(MacrosTest, DisallowCopyAndAssign) {
TestDisallowCopyAndAssignClass x;
x.NoOp();
TestDisallowCopyAndAssignClass y(789);
y.NoOp();
}
// Test that |MOJO_ARRAYSIZE()| works in a |static_assert()|.
const int kGlobalArray[5] = {1, 2, 3, 4, 5};
static_assert(MOJO_ARRAYSIZE(kGlobalArray) == 5u,
"MOJO_ARRAY_SIZE() failed in static_assert()");
TEST(MacrosTest, ArraySize) {
double local_array[4] = {6.7, 7.8, 8.9, 9.0};
// MSVS considers this local variable unused since MOJO_ARRAYSIZE only takes
// the size of the type of the local and not the values itself.
MOJO_ALLOW_UNUSED_LOCAL(local_array);
EXPECT_EQ(4u, MOJO_ARRAYSIZE(local_array));
// Prevent gcc unneeded-internal-declaration warning.
MOJO_ALLOW_UNUSED_LOCAL(kGlobalArray);
}
// Note: MSVS is very strict (and arguably buggy) about warnings for classes
// defined in a local scope, so define these globally.
class MoveOnlyInt {
public:
MoveOnlyInt() : is_set_(false), value_() {}
explicit MoveOnlyInt(int value) : is_set_(true), value_(value) {}
~MoveOnlyInt() {}
// Move-only constructor and operator=.
MoveOnlyInt(MoveOnlyInt&& other) { *this = other.Pass(); }
MoveOnlyInt& operator=(MoveOnlyInt&& other) {
if (&other != this) {
is_set_ = other.is_set_;
value_ = other.value_;
other.is_set_ = false;
}
return *this;
}
int value() const {
assert(is_set());
return value_;
}
bool is_set() const { return is_set_; }
private:
bool is_set_;
int value_;
MOJO_MOVE_ONLY_TYPE(MoveOnlyInt);
};
TEST(MacrosTest, MoveOnlyType) {
MoveOnlyInt x(123);
EXPECT_TRUE(x.is_set());
EXPECT_EQ(123, x.value());
MoveOnlyInt y;
EXPECT_FALSE(y.is_set());
y = x.Pass();
EXPECT_FALSE(x.is_set());
EXPECT_TRUE(y.is_set());
EXPECT_EQ(123, y.value());
MoveOnlyInt z(y.Pass());
EXPECT_FALSE(y.is_set());
EXPECT_TRUE(z.is_set());
EXPECT_EQ(123, z.value());
z = z.Pass();
EXPECT_TRUE(z.is_set());
EXPECT_EQ(123, z.value());
}
// The test for |ignore_result()| is also just a compilation test. (Note that
// |MOJO_WARN_UNUSED_RESULT| can only be used in the prototype.
int ReturnsIntYouMustUse() MOJO_WARN_UNUSED_RESULT;
int ReturnsIntYouMustUse() {
return 123;
}
TEST(MacrosTest, IgnoreResult) {
ignore_result(ReturnsIntYouMustUse());
}
} // namespace
} // namespace mojo