// Copyright (c) 2010 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.

#import "gtest_mac.h"

#include <string>

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/googletest/src/googletest/include/gtest/internal/gtest-port.h"
#include "third_party/googletest/src/googletest/include/gtest/internal/gtest-string.h"

#ifdef GTEST_OS_MAC

#import <Foundation/Foundation.h>

namespace testing {
namespace internal {

static std::string StringFromNSString(NSString* string) {
  // Note that -[NSString UTF8String] is banned in chromium code because
  // base::SysNSStringToUTF8() is safer, but //testing isn't allowed to depend
  // on //base, so deliberately ignore that function ban.
  const char* utf_string = [string UTF8String];
  return utf_string ? std::string(utf_string) : std::string("(nil nsstring)");
}

// Handles nil values for |obj| properly by using safe printing of %@ in
// -stringWithFormat:.
std::string StringDescription(id<NSObject> obj) {
  return StringFromNSString([NSString stringWithFormat:@"%@", obj]);
}

// This overloaded version allows comparison between ObjC objects that conform
// to the NSObject protocol. Used to implement {ASSERT|EXPECT}_EQ().
GTEST_API_ AssertionResult CmpHelperNSEQ(const char* expected_expression,
                                         const char* actual_expression,
                                         id<NSObject> expected,
                                         id<NSObject> actual) {
  if (expected == actual || [expected isEqual:actual]) {
    return AssertionSuccess();
  }
  return EqFailure(expected_expression, actual_expression,
                   StringDescription(expected), StringDescription(actual),
                   false);
}

// This overloaded version allows comparison between ObjC objects that conform
// to the NSObject protocol. Used to implement {ASSERT|EXPECT}_NE().
GTEST_API_ AssertionResult CmpHelperNSNE(const char* expected_expression,
                                         const char* actual_expression,
                                         id<NSObject> expected,
                                         id<NSObject> actual) {
  if (expected != actual && ![expected isEqual:actual]) {
    return AssertionSuccess();
  }
  Message msg;
  msg << "Expected: (" << expected_expression << ") != (" << actual_expression
      << "), actual: " << StringDescription(expected)
      << " vs " << StringDescription(actual);
  return AssertionFailure(msg);
}

#if !defined(GTEST_OS_IOS)

GTEST_API_ AssertionResult CmpHelperNSEQ(const char* expected_expression,
                                         const char* actual_expression,
                                         const NSRect& expected,
                                         const NSRect& actual) {
  if (NSEqualRects(expected, actual)) {
    return AssertionSuccess();
  }
  return EqFailure(expected_expression, actual_expression,
                   StringFromNSString(NSStringFromRect(expected)),
                   StringFromNSString(NSStringFromRect(actual)), false);
}

GTEST_API_ AssertionResult CmpHelperNSNE(const char* expected_expression,
                                         const char* actual_expression,
                                         const NSRect& expected,
                                         const NSRect& actual) {
  if (!NSEqualRects(expected, actual)) {
    return AssertionSuccess();
  }
  Message msg;
  msg << "Expected: (" << expected_expression << ") != (" << actual_expression
      << "), actual: " << StringFromNSString(NSStringFromRect(expected))
      << " vs " << StringFromNSString(NSStringFromRect(actual));
  return AssertionFailure(msg);

}

GTEST_API_ AssertionResult CmpHelperNSEQ(const char* expected_expression,
                                         const char* actual_expression,
                                         const NSPoint& expected,
                                         const NSPoint& actual) {
  if (NSEqualPoints(expected, actual)) {
    return AssertionSuccess();
  }
  return EqFailure(expected_expression, actual_expression,
                   StringFromNSString(NSStringFromPoint(expected)),
                   StringFromNSString(NSStringFromPoint(actual)), false);
}

GTEST_API_ AssertionResult CmpHelperNSNE(const char* expected_expression,
                                         const char* actual_expression,
                                         const NSPoint& expected,
                                         const NSPoint& actual) {
  if (!NSEqualPoints(expected, actual)) {
    return AssertionSuccess();
  }
  Message msg;
  msg << "Expected: (" << expected_expression << ") != (" << actual_expression
      << "), actual: " << StringFromNSString(NSStringFromPoint(expected))
      << " vs " << StringFromNSString(NSStringFromPoint(actual));
  return AssertionFailure(msg);
}

GTEST_API_ AssertionResult CmpHelperNSEQ(const char* expected_expression,
                                         const char* actual_expression,
                                         const NSRange& expected,
                                         const NSRange& actual) {
  if (NSEqualRanges(expected, actual)) {
    return AssertionSuccess();
  }
  return EqFailure(expected_expression, actual_expression,
                   StringFromNSString(NSStringFromRange(expected)),
                   StringFromNSString(NSStringFromRange(actual)), false);
}

GTEST_API_ AssertionResult CmpHelperNSNE(const char* expected_expression,
                                         const char* actual_expression,
                                         const NSRange& expected,
                                         const NSRange& actual) {
  if (!NSEqualRanges(expected, actual)) {
    return AssertionSuccess();
  }
  Message msg;
  msg << "Expected: (" << expected_expression << ") != (" << actual_expression
      << "), actual: " << StringFromNSString(NSStringFromRange(expected))
      << " vs " << StringFromNSString(NSStringFromRange(actual));
  return AssertionFailure(msg);
}

#endif  // !GTEST_OS_IOS

}  // namespace internal
}  // namespace testing

#endif  // GTEST_OS_MAC
