// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/css_parser/ref_counted_util.h"

#include "gtest/gtest.h"

namespace cobalt {
namespace css_parser {

class RefCountedDummy : public base::RefCounted<RefCountedDummy> {};

TEST(RefCountedUtilTest, AddRefToNull) {
  RefCountedDummy* dummy_ptr = NULL;
  ASSERT_FALSE(AddRef(dummy_ptr));
}

TEST(RefCountedUtilTest, AddRefToNonNull) {
  RefCountedDummy* dummy_ptr = new RefCountedDummy();
  ASSERT_EQ(dummy_ptr, AddRef(dummy_ptr));
  EXPECT_TRUE(dummy_ptr->HasOneRef());
  dummy_ptr->Release();
}

TEST(RefCountedUtilTest, MakesScopedRefPtrFromNull) {
  RefCountedDummy* dummy_ptr = NULL;

  scoped_refptr<RefCountedDummy> dummy_refptr =
      MakeScopedRefPtrAndRelease(dummy_ptr);
  ASSERT_FALSE(dummy_refptr.get());
}

TEST(RefCountedUtilTest, MakesScopedRefPtrFromNonNull) {
  RefCountedDummy* dummy_ptr = AddRef(new RefCountedDummy());

  scoped_refptr<RefCountedDummy> dummy_refptr =
      MakeScopedRefPtrAndRelease(dummy_ptr);
  ASSERT_EQ(dummy_ptr, dummy_refptr.get());
  EXPECT_TRUE(dummy_refptr->HasOneRef());
}

}  // namespace css_parser
}  // namespace cobalt
