Skip to content

Commit

Permalink
Provide gtest printers for ui/gfx geometry types
Browse files Browse the repository at this point in the history
This provides PrintTo(..) functions for the geometric types in ui/gfx/
so that failing gtest assertions pretty-print the values instead of
dumping the bytes of the objects. This way gtest assertions on these
types can be written in the form:

  EXPECT_EQ(a, b);

instead of
  EXPECT_EQ(a.ToString(), b.ToString());

which is currently used (inconsistently) to provide more readable
failure messages.

This is a bit tricky since gtest uses streams and somewhat complicated
template expansion magic to pretty print values and we don't want to
link the stream-based code into production code paths. This declares the
PrintTo() functions in the headers defining each of the geometry types,
using the <iosfwd> header to keep stream bloat to a minimum, and defines
the formatters in gfx_test_support. This way every test that
instantiates these printers has to declare a dependency on
gfx_test_support or it fails to link, but a test does not have to
#include any particular header to see the correct printer declaration
and thus expand the template correctly.

If we were to declare the PrintTo() functions in a test only header such
a gfx_util.h then the pretty printers would work reliably only if
*every* target in a translation unit that instantiated the comparison
saw this declaration. If some unit tests in a target #included the
header and some did not then it would be intederminate whether the
template instantiation linked in to the test binary was the pretty
printed one or the hex dump one (and in practice this appears to be
inconsistent across clang and gcc for whatever reason).

Review URL: https://codereview.chromium.org/368903003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282270 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jamesr@chromium.org committed Jul 10, 2014
1 parent a5a068d commit a109fd0
Show file tree
Hide file tree
Showing 28 changed files with 256 additions and 78 deletions.
1 change: 1 addition & 0 deletions components/components_tests.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@
'../testing/gtest.gyp:gtest',
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_test_support',

'components_resources.gyp:components_resources',

Expand Down
5 changes: 4 additions & 1 deletion content/content_tests.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -1331,10 +1331,11 @@
'../testing/gtest.gyp:gtest',
'../third_party/WebKit/public/blink.gyp:blink',
'../ui/base/ui_base.gyp:ui_base',
'../v8/tools/gyp/v8.gyp:v8',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gfx/gfx.gyp:gfx_test_support',
'../ui/gl/gl.gyp:gl',
'../v8/tools/gyp/v8.gyp:v8',
# The following dependency provides the missing symbol
# HeapProfilerStart in Linux component builds.
'../webkit/child/webkit_child.gyp:webkit_child',
Expand Down Expand Up @@ -1391,6 +1392,7 @@
'../testing/gtest.gyp:gtest',
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_test_support',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gl/gl.gyp:gl',
'content.gyp:content',
Expand Down Expand Up @@ -1489,6 +1491,7 @@
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gfx/gfx.gyp:gfx_test_support',
'../ui/gl/gl.gyp:gl',
'content.gyp:content',
],
Expand Down
2 changes: 2 additions & 0 deletions gpu/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ test("gl_tests") {
"//testing/gtest",
"//third_party/angle:translator",
"//ui/gfx",
"//ui/gfx:gfx_test_support",
"//ui/gfx/geometry",
"//ui/gl",
#"//gpu/command_buffer/client", # These are all part of //gpu, needed?
Expand Down Expand Up @@ -230,6 +231,7 @@ test("gpu_unittests") {
"//testing/gtest",
"//third_party/angle:translator",
"//ui/gfx",
"//ui/gfx:gfx_test_support",
"//ui/gfx/geometry",
"//ui/gl",
"//gpu/command_buffer/client:gles2_c_lib",
Expand Down
2 changes: 2 additions & 0 deletions gpu/gpu.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
'../ui/gl/gl.gyp:gl',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gfx/gfx.gyp:gfx_test_support',
'command_buffer/command_buffer.gyp:gles2_utils',
'command_buffer_client',
'command_buffer_common',
Expand Down Expand Up @@ -304,6 +305,7 @@
'../testing/gtest.gyp:gtest',
'<(angle_path)/src/build_angle.gyp:translator',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_test_support',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gl/gl.gyp:gl',
'command_buffer/command_buffer.gyp:gles2_utils',
Expand Down
2 changes: 2 additions & 0 deletions media/media.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,7 @@
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gfx/gfx.gyp:gfx_test_support',
'../url/url.gyp:url_lib',
],
'sources': [
Expand Down Expand Up @@ -1296,6 +1297,7 @@
'../testing/perf/perf_test.gyp:perf_test',
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_test_support',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gl/gl.gyp:gl',
'media',
Expand Down
3 changes: 3 additions & 0 deletions mojo/mojo_services.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
'../testing/gtest.gyp:gtest',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gfx/gfx.gyp:gfx_test_support',
'mojo_geometry_lib',
'mojo_run_all_unittests',
'mojo_surfaces_bindings',
Expand Down Expand Up @@ -402,6 +403,8 @@
'../base/base.gyp:base',
'../base/base.gyp:test_support_base',
'../testing/gtest.gyp:gtest',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_test_support',
'mojo_environment_chromium',
'mojo_geometry_bindings',
'mojo_geometry_lib',
Expand Down
1 change: 1 addition & 0 deletions printing/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ test("printing_unittests") {
"//testing/gtest",
"//ui/base",
"//ui/gfx",
"//ui/gfx:gfx_test_support",
"//ui/gfx/geometry",
]
}
Expand Down
1 change: 1 addition & 0 deletions printing/printing.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@
'../ui/base/ui_base.gyp:ui_base',
'../ui/gfx/gfx.gyp:gfx',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gfx/gfx.gyp:gfx_test_support',
'printing',
],
'sources': [
Expand Down
1 change: 1 addition & 0 deletions ui/events/events.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
'<(DEPTH)/base/base.gyp:test_support_base',
'<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/testing/gtest.gyp:gtest',
'../gfx/gfx.gyp:gfx',
'../gfx/gfx.gyp:gfx_geometry',
'../gfx/gfx.gyp:gfx_test_support',
'dom4_keycode_converter',
Expand Down
1 change: 1 addition & 0 deletions ui/gfx/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ test("gfx_unittests") {

deps = [
":gfx",
":gfx_test_support",
"//base",
"//base/test:test_support",
"//testing/gtest",
Expand Down
8 changes: 8 additions & 0 deletions ui/gfx/geometry/box_f.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#ifndef UI_GFX_GEOMETRY_BOX_F_H_
#define UI_GFX_GEOMETRY_BOX_F_H_

#include <iosfwd>
#include <string>

#include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/vector3d_f.h"

Expand Down Expand Up @@ -155,6 +158,11 @@ inline BoxF operator+(const BoxF& b, const Vector3dF& v) {
b.depth());
}

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const BoxF& box, ::std::ostream* os);

} // namespace gfx

#endif // UI_GFX_GEOMETRY_BOX_F_H_
8 changes: 8 additions & 0 deletions ui/gfx/geometry/point.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#ifndef UI_GFX_GEOMETRY_POINT_H_
#define UI_GFX_GEOMETRY_POINT_H_

#include <iosfwd>
#include <string>

#include "ui/gfx/geometry/point_base.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/vector2d.h"
Expand Down Expand Up @@ -85,6 +88,11 @@ inline Point PointAtOffsetFromOrigin(const Vector2d& offset_from_origin) {
extern template class PointBase<Point, int, Vector2d>;
#endif

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const Point& point, ::std::ostream* os);

} // namespace gfx

#endif // UI_GFX_GEOMETRY_POINT_H_
6 changes: 6 additions & 0 deletions ui/gfx/geometry/point3_f.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef UI_GFX_GEOMETRY_POINT3_F_H_
#define UI_GFX_GEOMETRY_POINT3_F_H_

#include <iosfwd>
#include <string>

#include "ui/gfx/geometry/point_f.h"
Expand Down Expand Up @@ -115,6 +116,11 @@ inline Point3F ScalePoint(const Point3F& p, float scale) {
return ScalePoint(p, scale, scale, scale);
}

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const Point3F& point, ::std::ostream* os);

} // namespace gfx

#endif // UI_GFX_GEOMETRY_POINT3_F_H_
6 changes: 6 additions & 0 deletions ui/gfx/geometry/point_f.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef UI_GFX_GEOMETRY_POINT_F_H_
#define UI_GFX_GEOMETRY_POINT_F_H_

#include <iosfwd>
#include <string>

#include "ui/gfx/geometry/point_base.h"
Expand Down Expand Up @@ -70,6 +71,11 @@ inline PointF ScalePoint(const PointF& p, float scale) {
extern template class PointBase<PointF, float, Vector2dF>;
#endif

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const PointF& point, ::std::ostream* os);

} // namespace gfx

#endif // UI_GFX_GEOMETRY_POINT_F_H_
6 changes: 6 additions & 0 deletions ui/gfx/geometry/quad_f.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <algorithm>
#include <cmath>
#include <iosfwd>
#include <string>

#include "ui/gfx/geometry/point_f.h"
Expand Down Expand Up @@ -104,6 +105,11 @@ GFX_EXPORT QuadF operator+(const QuadF& lhs, const Vector2dF& rhs);
// inverse of the vector.
GFX_EXPORT QuadF operator-(const QuadF& lhs, const Vector2dF& rhs);

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const QuadF& quad, ::std::ostream* os);

} // namespace gfx

#endif // UI_GFX_GEOMETRY_QUAD_F_H_
51 changes: 25 additions & 26 deletions ui/gfx/geometry/quad_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,34 @@ TEST(QuadTest, Construction) {
QuadF q2(e, e, e, e);
QuadF q3(a, b, c, d);
QuadF q4(BoundingRect(a, c));
EXPECT_EQ(q1.ToString(), q2.ToString());
EXPECT_EQ(q3.ToString(), q4.ToString());
EXPECT_EQ(q1, q2);
EXPECT_EQ(q3, q4);

// Verify getters.
EXPECT_EQ(q3.p1().ToString(), a.ToString());
EXPECT_EQ(q3.p2().ToString(), b.ToString());
EXPECT_EQ(q3.p3().ToString(), c.ToString());
EXPECT_EQ(q3.p4().ToString(), d.ToString());
EXPECT_EQ(q3.p1(), a);
EXPECT_EQ(q3.p2(), b);
EXPECT_EQ(q3.p3(), c);
EXPECT_EQ(q3.p4(), d);

// Verify setters.
q3.set_p1(b);
q3.set_p2(c);
q3.set_p3(d);
q3.set_p4(a);
EXPECT_EQ(q3.p1().ToString(), b.ToString());
EXPECT_EQ(q3.p2().ToString(), c.ToString());
EXPECT_EQ(q3.p3().ToString(), d.ToString());
EXPECT_EQ(q3.p4().ToString(), a.ToString());
EXPECT_EQ(q3.p1(), b);
EXPECT_EQ(q3.p2(), c);
EXPECT_EQ(q3.p3(), d);
EXPECT_EQ(q3.p4(), a);

// Verify operator=(Rect)
EXPECT_NE(q1.ToString(), q4.ToString());
EXPECT_NE(q1, q4);
q1 = BoundingRect(a, c);
EXPECT_EQ(q1.ToString(), q4.ToString());
EXPECT_EQ(q1, q4);

// Verify operator=(Quad)
EXPECT_NE(q1.ToString(), q3.ToString());
EXPECT_NE(q1, q3);
q1 = q3;
EXPECT_EQ(q1.ToString(), q3.ToString());
EXPECT_EQ(q1, q3);
}

TEST(QuadTest, AddingVectors) {
Expand All @@ -64,8 +64,8 @@ TEST(QuadTest, AddingVectors) {
PointF(5.5f, -1.5f),
PointF(5.5f, -0.5f),
PointF(4.5f, -0.5f));
EXPECT_EQ(expected1.ToString(), added.ToString());
EXPECT_EQ(expected1.ToString(), q1.ToString());
EXPECT_EQ(expected1, added);
EXPECT_EQ(expected1, q1);

QuadF q2(a, b, c, d);
QuadF subtracted = q2 - v;
Expand All @@ -74,14 +74,14 @@ TEST(QuadTest, AddingVectors) {
PointF(-1.5f, 3.5f),
PointF(-1.5f, 4.5f),
PointF(-2.5f, 4.5f));
EXPECT_EQ(expected2.ToString(), subtracted.ToString());
EXPECT_EQ(expected2.ToString(), q2.ToString());
EXPECT_EQ(expected2, subtracted);
EXPECT_EQ(expected2, q2);

QuadF q3(a, b, c, d);
q3 += v;
q3 -= v;
EXPECT_EQ(QuadF(a, b, c, d).ToString(), q3.ToString());
EXPECT_EQ(q3.ToString(), (q3 + v - v).ToString());
EXPECT_EQ(QuadF(a, b, c, d), q3);
EXPECT_EQ(q3, (q3 + v - v));
}

TEST(QuadTest, IsRectilinear) {
Expand Down Expand Up @@ -237,7 +237,7 @@ TEST(QuadTest, IsCounterClockwise) {

TEST(QuadTest, BoundingBox) {
RectF r(3.2f, 5.4f, 7.007f, 12.01f);
EXPECT_EQ(r.ToString(), QuadF(r).BoundingBox().ToString());
EXPECT_EQ(r, QuadF(r).BoundingBox());

PointF a(1.3f, 1.4f);
PointF b(-0.7f, 4.9f);
Expand All @@ -247,8 +247,8 @@ TEST(QuadTest, BoundingBox) {
float top = 1.4f;
float right = 2.1f;
float bottom = 6.2f;
EXPECT_EQ(RectF(left, top, right - left, bottom - top).ToString(),
QuadF(a, b, c, d).BoundingBox().ToString());
EXPECT_EQ(RectF(left, top, right - left, bottom - top),
QuadF(a, b, c, d).BoundingBox());
}

TEST(QuadTest, ContainsPoint) {
Expand Down Expand Up @@ -348,12 +348,11 @@ TEST(QuadTest, Scale) {
PointF b_scaled = ScalePoint(b, 1.5f);
PointF c_scaled = ScalePoint(c, 1.5f);
PointF d_scaled = ScalePoint(d, 1.5f);
EXPECT_EQ(q1.ToString(),
QuadF(a_scaled, b_scaled, c_scaled, d_scaled).ToString());
EXPECT_EQ(q1, QuadF(a_scaled, b_scaled, c_scaled, d_scaled));

QuadF q2;
q2.Scale(1.5f);
EXPECT_EQ(q2.ToString(), q2.ToString());
EXPECT_EQ(q2, q2);
}

} // namespace gfx
6 changes: 6 additions & 0 deletions ui/gfx/geometry/rect.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define UI_GFX_GEOMETRY_RECT_H_

#include <cmath>
#include <iosfwd>
#include <string>

#include "ui/gfx/geometry/point.h"
Expand Down Expand Up @@ -134,6 +135,11 @@ inline Rect ScaleToEnclosedRect(const Rect& rect, float scale) {
extern template class RectBase<Rect, Point, Size, Insets, Vector2d, int>;
#endif

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const Rect& rect, ::std::ostream* os);

} // namespace gfx

#endif // UI_GFX_GEOMETRY_RECT_H_
6 changes: 6 additions & 0 deletions ui/gfx/geometry/rect_f.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef UI_GFX_GEOMETRY_RECT_F_H_
#define UI_GFX_GEOMETRY_RECT_F_H_

#include <iosfwd>
#include <string>

#include "ui/gfx/geometry/point_f.h"
Expand Down Expand Up @@ -108,6 +109,11 @@ GFX_EXPORT RectF BoundingRect(const PointF& p1, const PointF& p2);
extern template class RectBase<RectF, PointF, SizeF, InsetsF, Vector2dF, float>;
#endif

// This is declared here for use in gtest-based unit tests but is defined in
// the gfx_test_support target. Depend on that to use this in your unit test.
// This should not be used in production code - call ToString() instead.
void PrintTo(const RectF& rect, ::std::ostream* os);

} // namespace gfx

#endif // UI_GFX_GEOMETRY_RECT_F_H_
Loading

0 comments on commit a109fd0

Please sign in to comment.