Merge branch 'master' into fluid_traversal

Conflicts:
	Makefile
This commit is contained in:
Michaël Lemaire 2013-11-10 21:18:32 +01:00
commit ea8f7f6fb1
189 changed files with 70042 additions and 909 deletions

View file

@ -1,6 +1,6 @@
BUILDMODE=release BUILDMODE=release
BUILDPATH=./build/${BUILDMODE} BUILDPATH=./build/${BUILDMODE}
LIBRARY_PATH=${BUILDPATH}/rendering:${BUILDPATH}/exploring:${BUILDPATH}/system:${BUILDPATH}/basics:${BUILDPATH}/definition:${BUILDPATH}/render/opengl:${BUILDPATH}/render/software LIBRARY_PATH=${BUILDPATH}/rendering:${BUILDPATH}/exploring:${BUILDPATH}/system:${BUILDPATH}/basics:${BUILDPATH}/definition:${BUILDPATH}/render/opengl:${BUILDPATH}/render/software:${BUILDPATH}/tests/googletest
all:build all:build
@ -33,7 +33,7 @@ release:
+make BUILDMODE=release all +make BUILDMODE=release all
tests:build tests:build
LD_LIBRARY_PATH=$(LIBRARY_PATH) CK_DEFAULT_TIMEOUT=30 ${BUILDPATH}/testing/paysages-tests LD_LIBRARY_PATH=$(LIBRARY_PATH) ${BUILDPATH}/tests/paysages-tests
run_cli:build run_cli:build
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/controlling/paysages-cli LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/controlling/paysages-cli

View file

@ -9,6 +9,6 @@ SUBDIRS = \
render/software \ render/software \
render/opengl \ render/opengl \
editing \ editing \
controlling controlling \
tests/googletest \
#unix:SUBDIRS += testing tests tests

View file

@ -6,8 +6,8 @@
*/ */
#include "../rendering_global.h" #include "../rendering_global.h"
#include "rendering/tools/euclid.h" #include "../tools/euclid.h"
#include "rendering/tools/curve.h" #include "../tools/curve.h"
namespace paysages { namespace paysages {
namespace system { namespace system {

View file

@ -5,14 +5,8 @@
#include "System.h" #include "System.h"
int tests_cpu_count; int tests_cpu_count;
extern void test_euclid_case(Suite* s);
extern void test_camera_case(Suite* s);
extern void test_clouds_case(Suite* s);
extern void test_render_case(Suite* s); extern void test_render_case(Suite* s);
extern void test_noise_case(Suite* s);
extern void test_terrain_painting_case(Suite* s); extern void test_terrain_painting_case(Suite* s);
extern void test_bruneton_case(Suite* s);
extern void test_pack_case(Suite* s);
extern void test_zone_case(Suite* s); extern void test_zone_case(Suite* s);
int main(int argc, char** argv) int main(int argc, char** argv)
@ -25,14 +19,8 @@ int main(int argc, char** argv)
tests_cpu_count = systemGetCoreCount(); tests_cpu_count = systemGetCoreCount();
/* TODO Find a way to automate this */ /* TODO Find a way to automate this */
test_euclid_case(s);
test_camera_case(s);
test_clouds_case(s);
test_render_case(s); test_render_case(s);
test_noise_case(s);
test_terrain_painting_case(s); test_terrain_painting_case(s);
test_bruneton_case(s);
test_pack_case(s);
test_zone_case(s); test_zone_case(s);
SRunner *sr = srunner_create(s); SRunner *sr = srunner_create(s);

View file

@ -1,474 +0,0 @@
#include "testing/common.h"
#include "rendering/renderer.h"
#include "rendering/tools.h"
#include "rendering/clouds/public.h"
#include "rendering/clouds/clo_density.h"
#include "rendering/clouds/clo_walking.h"
START_TEST(test_clouds_density)
{
/* Setup */
double x, y, z;
CloudsLayerDefinition* layer;
layer = cloudsGetLayerType().callback_create();
/* Test default coverage (empty) */
for (x = -10.0; x < 10.0; x += 10.0)
{
for (y = -10.0; y < 10.0; y += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, y, z)), 0.0);
}
}
}
/* Test coverage by altitude */
layer->base_coverage = 1.0;
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
layer->base_coverage = 1.0;
noiseForceValue(layer->_coverage_noise, 1.0);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 1.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.5);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.5);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
}
}
layer->base_coverage = 0.5;
noiseForceValue(layer->_coverage_noise, 1.0);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 0.5);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.25);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.25);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
}
}
layer->base_coverage = 1.0;
noiseForceValue(layer->_coverage_noise, 0.5);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 0.5);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.25);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.25);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ck_assert_double_eq(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
}
}
/* TODO Test fake renderer */
/* TODO Test real renderer */
/* Teardown */
cloudsGetLayerType().callback_delete(layer);
}
END_TEST
START_TEST(test_clouds_walking_boundaries)
{
Vector3 start, end;
int result;
CloudsLayerDefinition* layer;
layer = cloudsGetLayerType().callback_create();
layer->base_coverage = 1.0;
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
/* Basic cases */
start = v3(0.0, -3.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, 3.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 1);
ck_assert_vector_values(start, 0.0, -1.0, 0.0);
ck_assert_vector_values(end, 0.0, 1.0, 0.0);
start = v3(0.0, 0.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 1);
ck_assert_vector_values(start, 0.0, 0.0, 0.0);
ck_assert_vector_values(end, 0.0, 1.0, 0.0);
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 1);
ck_assert_vector_values(start, 0.0, -1.0, 0.0);
ck_assert_vector_values(end, 0.0, 0.0, 0.0);
/* Basic cases (inverted) */
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, -3.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, 3.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 1);
ck_assert_vector_values(start, 0.0, 1.0, 0.0);
ck_assert_vector_values(end, 0.0, -1.0, 0.0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 1);
ck_assert_vector_values(start, 0.0, 1.0, 0.0);
ck_assert_vector_values(end, 0.0, 0.0, 0.0);
start = v3(0.0, 0.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 1);
ck_assert_vector_values(start, 0.0, 0.0, 0.0);
ck_assert_vector_values(end, 0.0, -1.0, 0.0);
/* Horizontal cases */
start = v3(0.0, 2.0, 0.0);
end = v3(10.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, 1.00001, 0.0);
end = v3(10.0, 1.00001, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, -1.00001, 0.0);
end = v3(10.0, -1.00001, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, -2.0, 0.0);
end = v3(10.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 0);
start = v3(0.0, 0.0, 0.0);
end = v3(10.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ck_assert_int_eq(result, 1);
ck_assert_vector_values(start, 0.0, 0.0, 0.0);
ck_assert_vector_values(end, 10.0, 0.0, 0.0);
cloudsGetLayerType().callback_delete(layer);
}
END_TEST
static double _getLayerDensitySinX(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location)
{
UNUSED(renderer);
UNUSED(layer);
double density = sin(location.x * (2.0 * M_PI));
return (density > 0.0) ? density : 0.0;
}
static double _getEdgeDensitySquared(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 location, double edge_density)
{
UNUSED(renderer);
UNUSED(layer);
UNUSED(location);
return edge_density * edge_density;
}
START_TEST(test_clouds_walking)
{
/* Init */
CloudsLayerDefinition* layer;
layer = cloudsGetLayerType().callback_create();
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
Renderer* renderer;
renderer = rendererCreate();
renderer->render_quality = 8;
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(-0.4, 0.0, 0.0), v3(1.75, 0.0, 0.0));
CloudWalkerStepInfo* segment;
int result;
/* First step */
cloudsWalkerSetStepSize(walker, 0.3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_eq(segment->length, 0.3);
ck_assert_double_eq(segment->start.distance_from_start, 0.0);
ck_assert_vector_values(segment->start.location, -0.4, 0.0, 0.0);
ck_assert_double_eq(segment->start.global_density, 0.0);
ck_assert_double_eq(segment->end.distance_from_start, 0.3);
ck_assert_vector_values(segment->end.location, -0.1, 0.0, 0.0);
ck_assert_double_eq(segment->end.global_density, 0.0);
/* Second step */
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_eq(segment->length, 0.3);
ck_assert_double_eq(segment->start.distance_from_start, 0.3);
ck_assert_vector_values(segment->start.location, -0.1, 0.0, 0.0);
ck_assert_double_eq(segment->start.global_density, 0.0);
ck_assert_double_eq(segment->end.distance_from_start, 0.6);
ck_assert_vector_values(segment->end.location, 0.2, 0.0, 0.0);
ck_assert_double_gt(segment->end.global_density, 0.9);
/* Order to refine second step around the entry point */
cloudsWalkerOrderRefine(walker, 0.01);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_true(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_in_range(segment->length, 0.19, 0.20);
ck_assert_double_in_range(segment->start.distance_from_start, 0.40, 0.41);
ck_assert_double_in_range(segment->start.location.x, 0.0, 0.01);
ck_assert_double_gt(segment->start.global_density, 0.0);
ck_assert_double_eq(segment->end.distance_from_start, 0.6);
ck_assert_vector_values(segment->end.location, 0.2, 0.0, 0.0);
ck_assert_double_gt(segment->end.global_density, 0.9);
/* Third step, change step size */
cloudsWalkerSetStepSize(walker, 0.4);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_eq(segment->length, 0.4);
ck_assert_double_eq(segment->start.distance_from_start, 0.6);
ck_assert_vector_values(segment->start.location, 0.2, 0.0, 0.0);
ck_assert_double_gt(segment->start.global_density, 0.9);
ck_assert_double_eq(segment->end.distance_from_start, 1.0);
ck_assert_vector_values(segment->end.location, 0.6, 0.0, 0.0);
ck_assert_double_eq(segment->end.global_density, 0.0);
/* Refine exit point */
cloudsWalkerOrderRefine(walker, 0.001);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_true(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_in_range(segment->length, 0.3, 0.301);
ck_assert_double_eq(segment->start.distance_from_start, 0.6);
ck_assert_vector_values(segment->start.location, 0.2, 0.0, 0.0);
ck_assert_double_gt(segment->start.global_density, 0.9);
ck_assert_double_in_range(segment->end.distance_from_start, 0.9, 0.901);
ck_assert_double_in_range(segment->end.location.x, 0.5, 0.501);
ck_assert_double_eq(segment->end.global_density, 0.0);
/* Find next entry point by skipping blank */
cloudsWalkerSetVoidSkipping(walker, 1);
cloudsWalkerSetStepSize(walker, 0.2);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_eq(segment->length, 0.2);
ck_assert_double_in_range(segment->start.distance_from_start, 1.2, 1.4);
ck_assert_double_in_range(segment->start.location.x, 0.8, 1.0);
ck_assert_double_eq(segment->start.global_density, 0.0);
ck_assert_double_in_range(segment->end.distance_from_start, 1.4, 1.6);
ck_assert_double_in_range(segment->end.location.x, 1.0, 1.2);
ck_assert_double_gt(segment->end.global_density, 0.0);
/* Refine entry point */
cloudsWalkerOrderRefine(walker, 0.01);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_true(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_in_range(segment->length, 0.0, 0.2);
ck_assert_double_in_range(segment->start.distance_from_start, 1.4, 1.41);
ck_assert_double_in_range(segment->start.location.x, 1.0, 1.01);
ck_assert_double_gt(segment->start.global_density, 0.0);
ck_assert_double_in_range(segment->end.distance_from_start, 1.41, 1.6);
ck_assert_double_in_range(segment->end.location.x, 1.01, 1.2);
ck_assert_double_gt(segment->end.global_density, 0.0);
/* Subdivide entry for more detail */
CloudWalkerStepInfo parent = *segment;
cloudsWalkerOrderSubdivide(walker, 3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_true(segment->subdivided);
ck_assert_double_eq(segment->length, parent.length / 3.0);
ck_assert_double_eq(segment->start.distance_from_start, parent.start.distance_from_start);
ck_assert_double_eq(segment->start.location.x, parent.start.location.x);
ck_assert_double_eq(segment->end.distance_from_start, parent.start.distance_from_start + segment->length);
ck_assert_double_eq(segment->end.location.x, parent.start.location.x + segment->length);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_true(segment->subdivided);
ck_assert_double_eq(segment->length, parent.length / 3.0);
ck_assert_double_eq(segment->start.distance_from_start, parent.start.distance_from_start + segment->length);
ck_assert_double_eq(segment->start.location.x, parent.start.location.x + segment->length);
ck_assert_double_eq(segment->end.distance_from_start, parent.start.distance_from_start + 2.0 * segment->length);
ck_assert_double_eq(segment->end.location.x, parent.start.location.x + 2.0 * segment->length);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_true(segment->subdivided);
ck_assert_double_eq(segment->length, parent.length / 3.0);
ck_assert_double_eq(segment->start.distance_from_start, parent.start.distance_from_start + 2.0 * segment->length);
ck_assert_double_eq(segment->start.location.x, parent.start.location.x + 2.0 * segment->length);
ck_assert_double_eq(segment->end.distance_from_start, parent.end.distance_from_start);
ck_assert_double_eq(segment->end.location.x, parent.end.location.x);
/* After subdividing, normal walking resumes */
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_eq(segment->length, 0.2);
ck_assert_double_in_range(segment->start.distance_from_start, 1.41, 1.6);
ck_assert_double_in_range(segment->start.location.x, 1.01, 1.2);
ck_assert_double_gt(segment->start.global_density, 0.0);
ck_assert_double_in_range(segment->end.distance_from_start, 1.61, 1.8);
ck_assert_double_in_range(segment->end.location.x, 1.21, 1.4);
ck_assert_double_gt(segment->end.global_density, 0.0);
/* Exiting cloud again */
cloudsWalkerSetStepSize(walker, 0.3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_eq(segment->length, 0.3);
ck_assert_double_in_range(segment->start.distance_from_start, 1.61, 1.8);
ck_assert_double_in_range(segment->start.location.x, 1.21, 1.4);
ck_assert_double_gt(segment->start.global_density, 0.0);
ck_assert_double_in_range(segment->end.distance_from_start, 1.91, 2.1);
ck_assert_double_in_range(segment->end.location.x, 1.5, 1.7);
ck_assert_double_eq(segment->end.global_density, 0.0);
/* A step in the void without skipping */
cloudsWalkerSetVoidSkipping(walker, 0);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_false(segment->refined);
ck_assert_false(segment->subdivided);
ck_assert_double_eq(segment->length, 0.3);
ck_assert_double_in_range(segment->start.distance_from_start, 1.91, 2.1);
ck_assert_double_in_range(segment->start.location.x, 1.5, 1.7);
ck_assert_double_eq(segment->start.global_density, 0.0);
ck_assert_double_in_range(segment->end.distance_from_start, 2.21, 2.4);
ck_assert_double_in_range(segment->end.location.x, 1.8, 2.0);
ck_assert_double_eq(segment->end.global_density, 0.0);
/* Walker reached the lookup segment's end, it should stop */
result = cloudsWalkerPerformStep(walker);
ck_assert_int_eq(result, 0);
/* Clean up */
cloudsDeleteWalker(walker);
cloudsGetLayerType().callback_delete(layer);
rendererDelete(renderer);
}
END_TEST
START_TEST(test_clouds_walking_local)
{
/* Init */
CloudsLayerDefinition* layer;
layer = cloudsGetLayerType().callback_create();
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
Renderer* renderer;
renderer = rendererCreate();
renderer->render_quality = 8;
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
renderer->clouds->getEdgeDensity = _getEdgeDensitySquared;
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(0.0, 0.0, 0.0), v3(1.0, 0.0, 0.0));
CloudWalkerStepInfo* segment;
int result;
/* Test that local density is off by default */
cloudsWalkerSetStepSize(walker, 0.3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_double_eq(segment->length, 0.3);
ck_assert_double_eq(segment->start.global_density, 0.0);
ck_assert_double_eq(segment->start.local_density, 0.0);
ck_assert_double_eq(segment->end.global_density, 0.951056516295);
ck_assert_double_eq(segment->end.local_density, 0.0);
/* Test it's automatically enabled on subdivision */
cloudsWalkerOrderSubdivide(walker, 2);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ck_assert_int_eq(result, 1);
ck_assert_double_eq(segment->length, 0.15);
ck_assert_double_eq(segment->start.global_density, 0.0);
ck_assert_double_eq(segment->start.local_density, 0.0);
ck_assert_double_eq(segment->end.global_density, 0.809016994375);
ck_assert_double_eq(segment->end.local_density, 0.654508497187);
}
END_TEST
TEST_CASE(clouds,
test_clouds_density,
test_clouds_walking,
test_clouds_walking_boundaries,
test_clouds_walking_local)

View file

@ -1,134 +0,0 @@
#include "testing/common.h"
#include "rendering/tools/euclid.h"
static inline int _Vector3_cmp(Vector3 v1, Vector3 v2)
{
return fabs(v1.x - v2.z) >= 0.00000000001 && fabs(v1.y - v2.y) >= 0.00000000001 && fabs(v1.z - v2.z) >= 0.00000000001;
}
static inline void _Vector3_str(Vector3 v, char* buffer, int length)
{
snprintf(buffer, length, "(%f,%f,%f)", v.x, v.y, v.z);
}
DEFINE_COMPARE_ASSERT(Vector3, _Vector3_cmp, _Vector3_str);
START_TEST(test_euclid_angles)
{
ck_assert_double_eq(euclidGet2DAngle(0.0, 0.0), 0.0);
ck_assert_double_eq(euclidGet2DAngle(0.1, 0.0), 0.0);
ck_assert_double_eq(euclidGet2DAngle(1.0, 0.0), 0.0);
ck_assert_double_eq(euclidGet2DAngle(2.0, 0.0), 0.0);
ck_assert_double_eq(euclidGet2DAngle(0.0, 0.1), M_PI_2);
ck_assert_double_eq(euclidGet2DAngle(0.0, 1.0), M_PI_2);
ck_assert_double_eq(euclidGet2DAngle(0.0, 2.0), M_PI_2);
ck_assert_double_eq(euclidGet2DAngle(-0.1, 0.0), M_PI);
ck_assert_double_eq(euclidGet2DAngle(-1.0, 0.0), M_PI);
ck_assert_double_eq(euclidGet2DAngle(-2.0, 0.0), M_PI);
ck_assert_double_eq(euclidGet2DAngle(0.0, -0.1), 3.0 * M_PI_2);
ck_assert_double_eq(euclidGet2DAngle(0.0, -1.0), 3.0 * M_PI_2);
ck_assert_double_eq(euclidGet2DAngle(0.0, -2.0), 3.0 * M_PI_2);
ck_assert_double_eq(euclidGet2DAngle(0.5, 0.5), M_PI_4);
ck_assert_double_eq(euclidGet2DAngle(0.5, -0.5), 7.0 * M_PI_4);
ck_assert_double_eq(euclidGet2DAngle(-0.5, 0.5), 3.0 * M_PI_4);
ck_assert_double_eq(euclidGet2DAngle(-0.5, -0.5), 5.0 * M_PI_4);
}
END_TEST
START_TEST(test_vectors)
{
Vector3 v1, v2, v3;
/* Test scaling */
v1.x = 0.0;
v1.y = -4.3;
v1.z = 8.2;
v2.x = 0.0;
v2.y = -8.6;
v2.z = 16.4;
v3.x = 0.0;
v3.y = 2.15;
v3.z = -4.1;
ck_assert_generic_eq(Vector3, v3Scale(v1, 2.0), v2);
ck_assert_generic_eq(Vector3, v3Scale(v1, -0.5), v3);
}
END_TEST
START_TEST(test_vectors_spherical)
{
Vector3 v1;
VectorSpherical v2;
/* Test conversion to spherical */
v1.x = 0.0;
v1.y = 0.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, 0.0);
ck_assert_double_eq(v2.phi, 0.0);
ck_assert_double_eq(v2.theta, 0.0);
v1.x = 1.0;
v1.y = 0.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, 1.0);
ck_assert_double_eq(v2.phi, 0.0);
ck_assert_double_eq(v2.theta, 0.0);
v1.x = -1.0;
v1.y = 0.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, 1.0);
ck_assert_double_eq(v2.phi, M_PI);
ck_assert_double_eq(v2.theta, 0.0);
v1.x = 0.0;
v1.y = 1.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, 1.0);
ck_assert_double_eq(v2.phi, 0.0);
ck_assert_double_eq(v2.theta, M_PI_2);
v1.x = 0.0;
v1.y = -1.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, 1.0);
ck_assert_double_eq(v2.phi, 0.0);
ck_assert_double_eq(v2.theta, -M_PI_2);
v1.x = 0.0;
v1.y = 0.0;
v1.z = 1.0;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, 1.0);
ck_assert_double_eq(v2.phi, 3.0 * M_PI_2);
ck_assert_double_eq(v2.theta, 0.0);
v1.x = 0.0;
v1.y = 0.0;
v1.z = -1.0;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, 1.0);
ck_assert_double_eq(v2.phi, M_PI_2);
ck_assert_double_eq(v2.theta, 0.0);
v1.x = v1.y = v1.z = 0.5;
v2 = v3ToSpherical(v1);
ck_assert_double_eq(v2.r, sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5));
ck_assert_double_eq(v2.phi, 7.0 * M_PI_4);
ck_assert_double_eq(v2.theta, M_PI_2 - 0.955316618125);
}
END_TEST
TEST_CASE(euclid, test_euclid_angles, test_vectors, test_vectors_spherical)

View file

@ -1,78 +0,0 @@
#include "testing/common.h"
#include "rendering/noise.h"
START_TEST(test_noise_range)
{
NoiseGenerator* noise;
double minvalue, maxvalue;
noise = noiseCreateGenerator();
noiseAddLevelSimple(noise, 0.1, -1.0, 1.0);
noiseAddLevelSimple(noise, 0.2, -0.5, 0.2);
noiseAddLevelSimple(noise, 0.4, -0.3, 1.2);
noiseValidate(noise);
noiseGetRange(noise, &minvalue, &maxvalue);
ck_assert_double_eq(minvalue, -1.8);
ck_assert_double_eq(maxvalue, 2.4);
}
END_TEST
START_TEST(test_noise_normalize)
{
int x;
NoiseGenerator* noise;
noise = noiseCreateGenerator();
/* Symmetric case */
noiseAddLevelsSimple(noise, 10, 1.0, -4.0, 4.0, 0.5);
noiseValidate(noise);
noiseNormalizeAmplitude(noise, -1.0, 1.0, 0);
for (x = 0; x < 1000; x++)
{
double value = noiseGet1DTotal(noise, 0.01 * (double)x);
ck_assert_double_in_range(value, -1.0, 1.0);
}
/* Target center differs from current center */
noiseClearLevels(noise);
noiseAddLevelsSimple(noise, 10, 1.0, -5.0, 5.0, 0.5);
noiseValidate(noise);
noiseNormalizeAmplitude(noise, 0.0, 1.0, 0);
for (x = 0; x < 1000; x++)
{
double value = noiseGet1DTotal(noise, 0.01 * (double)x);
ck_assert_double_in_range(value, 0.0, 1.0);
}
/* Asymmetric range */
noiseClearLevels(noise);
noiseAddLevelsSimple(noise, 10, 1.0, 0.0, 10.0, 0.0);
noiseValidate(noise);
noiseNormalizeAmplitude(noise, 0.0, 1.0, 0);
for (x = 0; x < 1000; x++)
{
double value = noiseGet1DTotal(noise, 0.01 * (double)x);
ck_assert_double_in_range(value, 0.0, 1.0);
}
/* Complex asymmetric case */
noiseClearLevels(noise);
noiseAddLevelsSimple(noise, 3, 1.0, -2.0, 8.0, 0.3);
noiseValidate(noise);
noiseNormalizeAmplitude(noise, -2.0, 4.0, 0.0);
for (x = 0; x < 1000; x++)
{
double value = noiseGet1DTotal(noise, 0.01 * (double)x);
ck_assert_double_in_range(value, -2.0, 4.0);
}
noiseDeleteGenerator(noise);
}
END_TEST
TEST_CASE(noise, test_noise_range, test_noise_normalize)

View file

@ -1,54 +0,0 @@
#include "testing/common.h"
#include "PackStream.h"
START_TEST(testPack)
{
PackStream* stream;
int i;
int data_i;
double data_d;
char* data_s;
char buffer[100];
/* Writing to pack */
stream = packWriteFile("/tmp/test_paysages_pack");
for (i = 0; i < 5; i++)
{
data_i = i;
packWriteInt(stream, &data_i);
data_d = (double)i;
packWriteDouble(stream, &data_d);
data_s = "Testing string 0123 (accentué) !";
packWriteString(stream, data_s, 100);
packWriteString(stream, data_s, 4);
packWriteString(stream, data_s, 5);
}
packCloseStream(stream);
/* Reading from pack */
stream = packReadFile("/tmp/test_paysages_pack");
for (i = 0; i < 5; i++)
{
packReadInt(stream, &data_i);
ck_assert_int_eq(data_i, i);
packReadDouble(stream, &data_d);
ck_assert_double_eq(data_d, (double)i);
packReadString(stream, buffer, 100);
ck_assert_str_eq(buffer, "Testing string 0123 (accentué) !");
packReadString(stream, buffer, 4);
ck_assert_str_eq(buffer, "Tes");
packReadString(stream, buffer, 3);
ck_assert_str_eq(buffer, "Te");
}
packCloseStream(stream);
}
END_TEST
TEST_CASE(pack,
testPack)

View file

@ -15,13 +15,6 @@ INCLUDEPATH += $$PWD/..
SOURCES += main.c \ SOURCES += main.c \
test_terrain_painting.c \ test_terrain_painting.c \
test_render.c \
test_pack.c \
test_noise.c \
test_euclid.c \
test_clouds.c \
test_camera.c \
test_bruneton.c \
test_zone.c test_zone.c
HEADERS += \ HEADERS += \

View file

@ -1,16 +1,32 @@
#ifndef BASETESTCASE_H #ifndef BASETESTCASE_H
#define BASETESTCASE_H #define BASETESTCASE_H
#include <cppunit/TestFixture.h> #include "gtest/gtest.h"
#include <cppunit/TestSuite.h>
#include <cppunit/TestCaller.h>
#include <cppunit/extensions/HelperMacros.h>
using namespace CppUnit;
class BaseTestCase: public TestFixture #undef EXPECT_DOUBLE_EQ
#define EXPECT_DOUBLE_EQ(_expected_, _value_) \
EXPECT_NEAR(_expected_, _value_, 0.0000000001)
#undef ASSERT_DOUBLE_EQ
#define ASSERT_DOUBLE_EQ(_expected_, _value_) \
ASSERT_NEAR(_expected_, _value_, 0.0000000001)
#define EXPECT_DOUBLE_IN_RANGE(_value_, _min_, _max_) \
EXPECT_GT(_value_, _min_); EXPECT_LT(_value_, _max_)
#define ASSERT_DOUBLE_IN_RANGE(_value_, _min_, _max_) \
ASSERT_GT(_value_, _min_); ASSERT_LT(_value_, _max_)
#define EXPECT_COLOR_RGBA(_col_, _r_, _g_, _b_, _a_) \
EXPECT_DOUBLE_EQ(_col_.r, _r_); EXPECT_DOUBLE_EQ(_col_.g, _g_); EXPECT_DOUBLE_EQ(_col_.b, _b_); EXPECT_DOUBLE_EQ(_col_.a, _a_)
#define ASSERT_COLOR_RGBA(_col_, _r_, _g_, _b_, _a_) \
EXPECT_DOUBLE_EQ(_col_.r, _r_); EXPECT_DOUBLE_EQ(_col_.g, _g_); EXPECT_DOUBLE_EQ(_col_.b, _b_); EXPECT_DOUBLE_EQ(_col_.a, _a_)
#define EXPECT_VECTOR3_COORDS(_vec_, _x_, _y_, _z_) \
EXPECT_DOUBLE_EQ(_vec_.x, _x_); EXPECT_DOUBLE_EQ(_vec_.y, _y_); EXPECT_DOUBLE_EQ(_vec_.z, _z_)
#define ASSERT_VECTOR3_COORDS(_vec_, _x_, _y_, _z_) \
ASSERT_DOUBLE_EQ(_vec_.x, _x_); ASSERT_DOUBLE_EQ(_vec_.y, _y_); ASSERT_DOUBLE_EQ(_vec_.z, _z_)
class BaseTestCase: public ::testing::Test
{ {
public:
BaseTestCase();
}; };
#endif // BASETESTCASE_H #endif // BASETESTCASE_H

View file

@ -1,16 +1,21 @@
#include "testing/common.h" #include "BaseTestCase.h"
#include "tools/color.h"
#include "camera.h"
#include "renderer.h"
#include "atmosphere/public.h"
#include "Scenery.h"
#include "System.h" #include "System.h"
#include "rendering/Scenery.h"
#define OUTPUT_WIDTH 400 #define OUTPUT_WIDTH 400
#define OUTPUT_HEIGHT 300 #define OUTPUT_HEIGHT 300
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data) static Color _postProcessFragment(Renderer* renderer, Vector3 location, void*)
{ {
return renderer->atmosphere->applyAerialPerspective(renderer, location, COLOR_BLACK).final; return renderer->atmosphere->applyAerialPerspective(renderer, location, COLOR_BLACK).final;
} }
START_TEST(testBrunetonAerialPerspective) TEST(Bruneton, AerialPerspective1)
{ {
Renderer* renderer = sceneryCreateStandardRenderer(); Renderer* renderer = sceneryCreateStandardRenderer();
renderer->render_width = 800; renderer->render_width = 800;
@ -31,17 +36,16 @@ START_TEST(testBrunetonAerialPerspective)
renderer->pushQuad(renderer, v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL); renderer->pushQuad(renderer, v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL);
renderer->pushQuad(renderer, v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL); renderer->pushQuad(renderer, v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL);
renderer->pushQuad(renderer, v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL); renderer->pushQuad(renderer, v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL);
renderPostProcess(renderer->render_area, tests_cpu_count); renderPostProcess(renderer->render_area, System::getCoreCount());
renderSaveToFile(renderer->render_area, "./output/test_bruneton_perspective.png"); renderSaveToFile(renderer->render_area, "./output/test_bruneton_perspective.png");
rendererDelete(renderer); rendererDelete(renderer);
} }
END_TEST
START_TEST(testBrunetonAerialPerspective1) TEST(Bruneton, AerialPerspective2)
{ {
AtmosphereDefinition* atmo = AtmosphereDefinitionClass.create(); AtmosphereDefinition* atmo = (AtmosphereDefinition*)AtmosphereDefinitionClass.create();
sceneryGetAtmosphere(atmo); sceneryGetAtmosphere(atmo);
atmo->hour = 6; atmo->hour = 6;
atmo->minute = 30; atmo->minute = 30;
@ -67,15 +71,9 @@ START_TEST(testBrunetonAerialPerspective1)
renderer->pushQuad(renderer, v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL); renderer->pushQuad(renderer, v3(15.0, -10.0, -5.0), v3(15.0, -10.0, 0.0), v3(15.0, 50.0, 0.0), v3(15.0, 50.0, -5.0), _postProcessFragment, NULL);
renderer->pushQuad(renderer, v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL); renderer->pushQuad(renderer, v3(20.0, -10.0, 5.0), v3(20.0, -10.0, 10.0), v3(20.0, 50.0, 10.0), v3(20.0, 50.0, 5.0), _postProcessFragment, NULL);
renderer->pushQuad(renderer, v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL); renderer->pushQuad(renderer, v3(30.0, -10.0, 25.0), v3(30.0, -10.0, 30.0), v3(30.0, 50.0, 30.0), v3(30.0, 50.0, 25.0), _postProcessFragment, NULL);
renderPostProcess(renderer->render_area, tests_cpu_count); renderPostProcess(renderer->render_area, System::getCoreCount());
renderSaveToFile(renderer->render_area, "./output/test_bruneton_perspective1.png"); renderSaveToFile(renderer->render_area, "./output/test_bruneton_perspective1.png");
rendererDelete(renderer); rendererDelete(renderer);
} }
END_TEST
TEST_CASE(bruneton,
testBrunetonAerialPerspective,
testBrunetonAerialPerspective1)

View file

@ -1,8 +1,8 @@
#include "testing/common.h" #include "BaseTestCase.h"
#include "rendering/camera.h" #include "camera.h"
START_TEST(test_camera_definition) TEST(Camera, Definition)
{ {
CameraDefinition* cam; CameraDefinition* cam;
cam = cameraCreateDefinition(); cam = cameraCreateDefinition();
@ -10,14 +10,13 @@ START_TEST(test_camera_definition)
cameraSetLocationCoords(cam, 0.0, 1.0, 1.0); cameraSetLocationCoords(cam, 0.0, 1.0, 1.0);
cameraSetTargetCoords(cam, 0.0, 0.0, 0.0); cameraSetTargetCoords(cam, 0.0, 0.0, 0.0);
ck_assert_vector_values(cameraGetLocation(cam), 0.0, 1.0, 1.0); EXPECT_VECTOR3_COORDS(cameraGetLocation(cam), 0.0, 1.0, 1.0);
ck_assert_vector_values(cameraGetTarget(cam), 0.0, 0.0, 0.0); EXPECT_VECTOR3_COORDS(cameraGetTarget(cam), 0.0, 0.0, 0.0);
cameraDeleteDefinition(cam); cameraDeleteDefinition(cam);
} }
END_TEST
START_TEST(test_camera_projection) TEST(Camera, Projection)
{ {
CameraDefinition* cam; CameraDefinition* cam;
cam = cameraCreateDefinition(); cam = cameraCreateDefinition();
@ -28,16 +27,15 @@ START_TEST(test_camera_projection)
/* Test the reversibility of projection */ /* Test the reversibility of projection */
Vector3 point = cameraProject(cam, v3(12.0, 5.2, -6.3)); Vector3 point = cameraProject(cam, v3(12.0, 5.2, -6.3));
point = cameraUnproject(cam, point); point = cameraUnproject(cam, point);
ck_assert_vector_values(point, 12.0, 5.2, -6.3); EXPECT_VECTOR3_COORDS(point, 12.0, 5.2, -6.3);
point = cameraProject(cam, v3(-25.1, 8.3, 1.3)); point = cameraProject(cam, v3(-25.1, 8.3, 1.3));
point = cameraUnproject(cam, point); point = cameraUnproject(cam, point);
ck_assert_vector_values(point, -25.1, 8.3, 1.3); EXPECT_VECTOR3_COORDS(point, -25.1, 8.3, 1.3);
cameraDeleteDefinition(cam); cameraDeleteDefinition(cam);
} }
END_TEST
START_TEST(test_camera_depth) TEST(Camera, Depth)
{ {
CameraDefinition* cam; CameraDefinition* cam;
cam = cameraCreateDefinition(); cam = cameraCreateDefinition();
@ -47,18 +45,11 @@ START_TEST(test_camera_depth)
/* Test the real depth getter */ /* Test the real depth getter */
Vector3 point = cameraProject(cam, v3(12.5, 0.0, 0.0)); Vector3 point = cameraProject(cam, v3(12.5, 0.0, 0.0));
ck_assert_double_eq(cameraGetRealDepth(cam, point), 12.5); ASSERT_DOUBLE_EQ(cameraGetRealDepth(cam, point), 12.5);
point = cameraProject(cam, v3(12.5, 8.0, -3.0)); point = cameraProject(cam, v3(12.5, 8.0, -3.0));
ck_assert_double_eq(cameraGetRealDepth(cam, point), 12.5); ASSERT_DOUBLE_EQ(cameraGetRealDepth(cam, point), 12.5);
point = cameraProject(cam, v3(12.5, 12.0, 58.0)); point = cameraProject(cam, v3(12.5, 12.0, 58.0));
ck_assert_double_eq(cameraGetRealDepth(cam, point), 12.5); ASSERT_DOUBLE_EQ(cameraGetRealDepth(cam, point), 12.5);
cameraDeleteDefinition(cam); cameraDeleteDefinition(cam);
} }
END_TEST
TEST_CASE(camera,
test_camera_definition,
test_camera_projection,
test_camera_depth)

459
src/tests/Clouds_Test.cpp Normal file
View file

@ -0,0 +1,459 @@
#include "BaseTestCase.h"
#include <cmath>
#include "renderer.h"
#include "clouds/public.h"
#include "clouds/clo_density.h"
#include "clouds/clo_walking.h"
#include "NoiseGenerator.h"
TEST(Clouds, Density)
{
/* Setup */
double x, y, z;
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
/* Test default coverage (empty) */
for (x = -10.0; x < 10.0; x += 10.0)
{
for (y = -10.0; y < 10.0; y += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, y, z)), 0.0);
}
}
}
/* Test coverage by altitude */
layer->base_coverage = 1.0;
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
layer->base_coverage = 1.0;
layer->_coverage_noise->forceValue(1.0);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 1.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
}
}
layer->base_coverage = 0.5;
layer->_coverage_noise->forceValue(1.0);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
}
}
layer->base_coverage = 1.0;
layer->_coverage_noise->forceValue(0.5);
for (x = -10.0; x < 10.0; x += 10.0)
{
for (z = -10.0; z < 10.0; z += 10.0)
{
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.0, z)), 0.5);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, 1.5, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -0.5, z)), 0.25);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.0, z)), 0.0);
ASSERT_DOUBLE_EQ(cloudsGetLayerCoverage(layer, v3(x, -1.5, z)), 0.0);
}
}
/* TODO Test fake renderer */
/* TODO Test real renderer */
/* Teardown */
cloudsGetLayerType().callback_delete(layer);
}
TEST(Clouds, WalkingBoundaries)
{
Vector3 start, end;
int result;
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
layer->base_coverage = 1.0;
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
/* Basic cases */
start = v3(0.0, -3.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, 3.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, -1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 1.0, 0.0);
start = v3(0.0, 0.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 0.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 1.0, 0.0);
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, -1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 0.0, 0.0);
/* Basic cases (inverted) */
start = v3(0.0, -2.0, 0.0);
end = v3(0.0, -3.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 3.0, 0.0);
end = v3(0.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, -1.0, 0.0);
start = v3(0.0, 2.0, 0.0);
end = v3(0.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 1.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, 0.0, 0.0);
start = v3(0.0, 0.0, 0.0);
end = v3(0.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 0.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 0.0, -1.0, 0.0);
/* Horizontal cases */
start = v3(0.0, 2.0, 0.0);
end = v3(10.0, 2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 1.00001, 0.0);
end = v3(10.0, 1.00001, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, -1.00001, 0.0);
end = v3(10.0, -1.00001, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, -2.0, 0.0);
end = v3(10.0, -2.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 0);
start = v3(0.0, 0.0, 0.0);
end = v3(10.0, 0.0, 0.0);
result = cloudsOptimizeWalkingBounds(layer, &start, &end);
ASSERT_EQ(result, 1);
ASSERT_VECTOR3_COORDS(start, 0.0, 0.0, 0.0);
ASSERT_VECTOR3_COORDS(end, 10.0, 0.0, 0.0);
cloudsGetLayerType().callback_delete(layer);
}
static double _getLayerDensitySinX(Renderer*, CloudsLayerDefinition*, Vector3 location)
{
double density = sin(location.x * (2.0 * M_PI));
return (density > 0.0) ? density : 0.0;
}
static double _getEdgeDensitySquared(Renderer*, CloudsLayerDefinition*, Vector3, double edge_density)
{
return edge_density * edge_density;
}
TEST(Clouds, Walking)
{
/* Init */
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
Renderer* renderer;
renderer = rendererCreate();
renderer->render_quality = 8;
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(-0.4, 0.0, 0.0), v3(1.75, 0.0, 0.0));
CloudWalkerStepInfo* segment;
int result;
/* First step */
cloudsWalkerSetStepSize(walker, 0.3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, 0.3);
ASSERT_DOUBLE_EQ(segment->start.distance_from_start, 0.0);
ASSERT_VECTOR3_COORDS(segment->start.location, -0.4, 0.0, 0.0);
ASSERT_DOUBLE_EQ(segment->start.global_density, 0.0);
ASSERT_DOUBLE_EQ(segment->end.distance_from_start, 0.3);
ASSERT_VECTOR3_COORDS(segment->end.location, -0.1, 0.0, 0.0);
ASSERT_DOUBLE_EQ(segment->end.global_density, 0.0);
/* Second step */
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, 0.3);
ASSERT_DOUBLE_EQ(segment->start.distance_from_start, 0.3);
ASSERT_VECTOR3_COORDS(segment->start.location, -0.1, 0.0, 0.0);
ASSERT_DOUBLE_EQ(segment->start.global_density, 0.0);
ASSERT_DOUBLE_EQ(segment->end.distance_from_start, 0.6);
ASSERT_VECTOR3_COORDS(segment->end.location, 0.2, 0.0, 0.0);
ASSERT_GT(segment->end.global_density, 0.9);
/* Order to refine second step around the entry point */
cloudsWalkerOrderRefine(walker, 0.01);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_TRUE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_IN_RANGE(segment->length, 0.19, 0.20);
ASSERT_DOUBLE_IN_RANGE(segment->start.distance_from_start, 0.40, 0.41);
ASSERT_DOUBLE_IN_RANGE(segment->start.location.x, 0.0, 0.01);
ASSERT_GT(segment->start.global_density, 0.0);
ASSERT_DOUBLE_EQ(segment->end.distance_from_start, 0.6);
ASSERT_VECTOR3_COORDS(segment->end.location, 0.2, 0.0, 0.0);
ASSERT_GT(segment->end.global_density, 0.9);
/* Third step, change step size */
cloudsWalkerSetStepSize(walker, 0.4);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, 0.4);
ASSERT_DOUBLE_EQ(segment->start.distance_from_start, 0.6);
ASSERT_VECTOR3_COORDS(segment->start.location, 0.2, 0.0, 0.0);
ASSERT_GT(segment->start.global_density, 0.9);
ASSERT_DOUBLE_EQ(segment->end.distance_from_start, 1.0);
ASSERT_VECTOR3_COORDS(segment->end.location, 0.6, 0.0, 0.0);
ASSERT_DOUBLE_EQ(segment->end.global_density, 0.0);
/* Refine exit point */
cloudsWalkerOrderRefine(walker, 0.001);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_TRUE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_IN_RANGE(segment->length, 0.3, 0.301);
ASSERT_DOUBLE_EQ(segment->start.distance_from_start, 0.6);
ASSERT_VECTOR3_COORDS(segment->start.location, 0.2, 0.0, 0.0);
ASSERT_GT(segment->start.global_density, 0.9);
ASSERT_DOUBLE_IN_RANGE(segment->end.distance_from_start, 0.9, 0.901);
ASSERT_DOUBLE_IN_RANGE(segment->end.location.x, 0.5, 0.501);
ASSERT_DOUBLE_EQ(segment->end.global_density, 0.0);
/* Find next entry point by skipping blank */
cloudsWalkerSetVoidSkipping(walker, 1);
cloudsWalkerSetStepSize(walker, 0.2);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, 0.2);
ASSERT_DOUBLE_IN_RANGE(segment->start.distance_from_start, 1.2, 1.4);
ASSERT_DOUBLE_IN_RANGE(segment->start.location.x, 0.8, 1.0);
ASSERT_DOUBLE_EQ(segment->start.global_density, 0.0);
ASSERT_DOUBLE_IN_RANGE(segment->end.distance_from_start, 1.4, 1.6);
ASSERT_DOUBLE_IN_RANGE(segment->end.location.x, 1.0, 1.2);
ASSERT_GT(segment->end.global_density, 0.0);
/* Refine entry point */
cloudsWalkerOrderRefine(walker, 0.01);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_TRUE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_IN_RANGE(segment->length, 0.0, 0.2);
ASSERT_DOUBLE_IN_RANGE(segment->start.distance_from_start, 1.4, 1.41);
ASSERT_DOUBLE_IN_RANGE(segment->start.location.x, 1.0, 1.01);
ASSERT_GT(segment->start.global_density, 0.0);
ASSERT_DOUBLE_IN_RANGE(segment->end.distance_from_start, 1.41, 1.6);
ASSERT_DOUBLE_IN_RANGE(segment->end.location.x, 1.01, 1.2);
ASSERT_GT(segment->end.global_density, 0.0);
/* Subdivide entry for more detail */
CloudWalkerStepInfo parent = *segment;
cloudsWalkerOrderSubdivide(walker, 3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_TRUE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, parent.length / 3.0);
ASSERT_DOUBLE_EQ(segment->start.distance_from_start, parent.start.distance_from_start);
ASSERT_DOUBLE_EQ(segment->start.location.x, parent.start.location.x);
ASSERT_DOUBLE_EQ(segment->end.distance_from_start, parent.start.distance_from_start + segment->length);
ASSERT_DOUBLE_EQ(segment->end.location.x, parent.start.location.x + segment->length);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_TRUE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, parent.length / 3.0);
ASSERT_DOUBLE_EQ(segment->start.distance_from_start, parent.start.distance_from_start + segment->length);
ASSERT_DOUBLE_EQ(segment->start.location.x, parent.start.location.x + segment->length);
ASSERT_DOUBLE_EQ(segment->end.distance_from_start, parent.start.distance_from_start + 2.0 * segment->length);
ASSERT_DOUBLE_EQ(segment->end.location.x, parent.start.location.x + 2.0 * segment->length);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_TRUE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, parent.length / 3.0);
ASSERT_DOUBLE_EQ(segment->start.distance_from_start, parent.start.distance_from_start + 2.0 * segment->length);
ASSERT_DOUBLE_EQ(segment->start.location.x, parent.start.location.x + 2.0 * segment->length);
ASSERT_DOUBLE_EQ(segment->end.distance_from_start, parent.end.distance_from_start);
ASSERT_DOUBLE_EQ(segment->end.location.x, parent.end.location.x);
/* After subdividing, normal walking resumes */
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, 0.2);
ASSERT_DOUBLE_IN_RANGE(segment->start.distance_from_start, 1.41, 1.6);
ASSERT_DOUBLE_IN_RANGE(segment->start.location.x, 1.01, 1.2);
ASSERT_GT(segment->start.global_density, 0.0);
ASSERT_DOUBLE_IN_RANGE(segment->end.distance_from_start, 1.61, 1.8);
ASSERT_DOUBLE_IN_RANGE(segment->end.location.x, 1.21, 1.4);
ASSERT_GT(segment->end.global_density, 0.0);
/* Exiting cloud again */
cloudsWalkerSetStepSize(walker, 0.3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, 0.3);
ASSERT_DOUBLE_IN_RANGE(segment->start.distance_from_start, 1.61, 1.8);
ASSERT_DOUBLE_IN_RANGE(segment->start.location.x, 1.21, 1.4);
ASSERT_GT(segment->start.global_density, 0.0);
ASSERT_DOUBLE_IN_RANGE(segment->end.distance_from_start, 1.91, 2.1);
ASSERT_DOUBLE_IN_RANGE(segment->end.location.x, 1.5, 1.7);
ASSERT_DOUBLE_EQ(segment->end.global_density, 0.0);
/* A step in the void without skipping */
cloudsWalkerSetVoidSkipping(walker, 0);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_FALSE(segment->refined);
ASSERT_FALSE(segment->subdivided);
ASSERT_DOUBLE_EQ(segment->length, 0.3);
ASSERT_DOUBLE_IN_RANGE(segment->start.distance_from_start, 1.91, 2.1);
ASSERT_DOUBLE_IN_RANGE(segment->start.location.x, 1.5, 1.7);
ASSERT_DOUBLE_EQ(segment->start.global_density, 0.0);
ASSERT_DOUBLE_IN_RANGE(segment->end.distance_from_start, 2.21, 2.4);
ASSERT_DOUBLE_IN_RANGE(segment->end.location.x, 1.8, 2.0);
ASSERT_DOUBLE_EQ(segment->end.global_density, 0.0);
/* Walker reached the lookup segment's end, it should stop */
result = cloudsWalkerPerformStep(walker);
ASSERT_EQ(result, 0);
/* Clean up */
cloudsDeleteWalker(walker);
cloudsGetLayerType().callback_delete(layer);
rendererDelete(renderer);
}
TEST(Clouds, WalkingLocal)
{
/* Init */
CloudsLayerDefinition* layer;
layer = (CloudsLayerDefinition*)cloudsGetLayerType().callback_create();
layer->lower_altitude = -1.0;
layer->thickness = 2.0;
cloudsGetLayerType().callback_validate(layer);
Renderer* renderer;
renderer = rendererCreate();
renderer->render_quality = 8;
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
renderer->clouds->getEdgeDensity = _getEdgeDensitySquared;
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(0.0, 0.0, 0.0), v3(1.0, 0.0, 0.0));
CloudWalkerStepInfo* segment;
int result;
/* Test that local density is off by default */
cloudsWalkerSetStepSize(walker, 0.3);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_DOUBLE_EQ(segment->length, 0.3);
ASSERT_DOUBLE_EQ(segment->start.global_density, 0.0);
ASSERT_DOUBLE_EQ(segment->start.local_density, 0.0);
ASSERT_DOUBLE_EQ(segment->end.global_density, 0.951056516295);
ASSERT_DOUBLE_EQ(segment->end.local_density, 0.0);
/* Test it's automatically enabled on subdivision */
cloudsWalkerOrderSubdivide(walker, 2);
result = cloudsWalkerPerformStep(walker);
segment = cloudsWalkerGetLastSegment(walker);
ASSERT_EQ(result, 1);
ASSERT_DOUBLE_EQ(segment->length, 0.15);
ASSERT_DOUBLE_EQ(segment->start.global_density, 0.0);
ASSERT_DOUBLE_EQ(segment->start.local_density, 0.0);
ASSERT_DOUBLE_EQ(segment->end.global_density, 0.809016994375);
ASSERT_DOUBLE_EQ(segment->end.local_density, 0.654508497187);
}

128
src/tests/Euclid_Test.cpp Normal file
View file

@ -0,0 +1,128 @@
#include "BaseTestCase.h"
#include <cmath>
#include "tools/euclid.h"
/*static inline int _Vector3_cmp(Vector3 v1, Vector3 v2)
{
return fabs(v1.x - v2.z) >= 0.00000000001 && fabs(v1.y - v2.y) >= 0.00000000001 && fabs(v1.z - v2.z) >= 0.00000000001;
}
static inline void _Vector3_str(Vector3 v, char* buffer, int length)
{
snprintf(buffer, length, "(%f,%f,%f)", v.x, v.y, v.z);
}
DEFINE_COMPARE_ASSERT(Vector3, _Vector3_cmp, _Vector3_str);*/
TEST(Euclid, get2DAngle)
{
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.0, 0.0), 0.0);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.1, 0.0), 0.0);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(1.0, 0.0), 0.0);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(2.0, 0.0), 0.0);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.0, 0.1), M_PI_2);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.0, 1.0), M_PI_2);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.0, 2.0), M_PI_2);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(-0.1, 0.0), M_PI);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(-1.0, 0.0), M_PI);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(-2.0, 0.0), M_PI);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.0, -0.1), 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.0, -1.0), 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.0, -2.0), 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.5, 0.5), M_PI_4);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(0.5, -0.5), 7.0 * M_PI_4);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(-0.5, 0.5), 3.0 * M_PI_4);
EXPECT_DOUBLE_EQ(euclidGet2DAngle(-0.5, -0.5), 5.0 * M_PI_4);
}
/*TEST(Euclid, Vector3)
{
Vector3 v1, v2, v3;
// Test scaling
v1.x = 0.0;
v1.y = -4.3;
v1.z = 8.2;
v2.x = 0.0;
v2.y = -8.6;
v2.z = 16.4;
v3.x = 0.0;
v3.y = 2.15;
v3.z = -4.1;
EXPECT_EQ(v3Scale(v1, 2.0), v2);
EXPECT_EQ(v3Scale(v1, -0.5), v3);
}*/
TEST(Euclid, VectorSpherical)
{
Vector3 v1;
VectorSpherical v2;
/* Test conversion to spherical */
v1.x = 0.0;
v1.y = 0.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, 0.0);
EXPECT_DOUBLE_EQ(v2.phi, 0.0);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = 1.0;
v1.y = 0.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, 0.0);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = -1.0;
v1.y = 0.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, M_PI);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = 0.0;
v1.y = 1.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, 0.0);
EXPECT_DOUBLE_EQ(v2.theta, M_PI_2);
v1.x = 0.0;
v1.y = -1.0;
v1.z = 0.0;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, 0.0);
EXPECT_DOUBLE_EQ(v2.theta, -M_PI_2);
v1.x = 0.0;
v1.y = 0.0;
v1.z = 1.0;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = 0.0;
v1.y = 0.0;
v1.z = -1.0;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, M_PI_2);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = v1.y = v1.z = 0.5;
v2 = v3ToSpherical(v1);
EXPECT_DOUBLE_EQ(v2.r, sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5));
EXPECT_DOUBLE_EQ(v2.phi, 7.0 * M_PI_4);
EXPECT_DOUBLE_EQ(v2.theta, M_PI_2 - 0.955316618125);
}

View file

@ -1,6 +1,7 @@
#include "Layers_Test.h" #include "BaseTestCase.h"
#include "Layers.h" #include "Layers.h"
#include "PackStream.h"
BaseDefinition* _construc1(Layers*) BaseDefinition* _construc1(Layers*)
{ {
@ -14,68 +15,68 @@ BaseDefinition* _construc2(Layers* parent)
return result; return result;
} }
void Layers_Test::testConstructor() TEST(Layers, Constructor)
{ {
Layers layers1(NULL, _construc1); Layers layers1(NULL, _construc1);
CPPUNIT_ASSERT_EQUAL(0, layers1.count()); EXPECT_EQ(0, layers1.count());
} }
void Layers_Test::testNullLayer() TEST(Layers, NullLayer)
{ {
Layers layers1(NULL, _construc1); Layers layers1(NULL, _construc1);
for (int i = -2; i < 5; i++) for (int i = -2; i < 5; i++)
{ {
BaseDefinition* layer = layers1.getLayer(0); BaseDefinition* layer = layers1.getLayer(0);
CPPUNIT_ASSERT(layer != NULL); EXPECT_NE((BaseDefinition*)NULL, layer);
CPPUNIT_ASSERT(NULL == layer->getParent()); EXPECT_EQ(NULL, layer->getParent());
CPPUNIT_ASSERT(layer == layer->getRoot()); EXPECT_EQ(layer, layer->getRoot());
CPPUNIT_ASSERT(QString() == layer->getName()); EXPECT_EQ(QString(), layer->getName());
} }
CPPUNIT_ASSERT_EQUAL(0, layers1.count()); EXPECT_EQ(0, layers1.count());
} }
void Layers_Test::testCopy() TEST(Layers, copy)
{ {
Layers layers1(NULL, _construc2); Layers layers1(NULL, _construc2);
layers1.addLayer(); layers1.addLayer();
CPPUNIT_ASSERT_EQUAL(1, layers1.count()); EXPECT_EQ(1, layers1.count());
// Copy with the same constructor // Copy with the same constructor
Layers layers2(NULL, _construc2); Layers layers2(NULL, _construc2);
CPPUNIT_ASSERT_EQUAL(0, layers2.count()); EXPECT_EQ(0, layers2.count());
layers1.copy(&layers2); layers1.copy(&layers2);
CPPUNIT_ASSERT_EQUAL(1, layers2.count()); EXPECT_EQ(1, layers2.count());
CPPUNIT_ASSERT(QString("test") == layers1.getLayer(0)->getName()); EXPECT_EQ(QString("test"), layers1.getLayer(0)->getName());
CPPUNIT_ASSERT(&layers1 == layers1.getLayer(0)->getParent()); EXPECT_EQ(&layers1, layers1.getLayer(0)->getParent());
CPPUNIT_ASSERT(QString("test") == layers2.getLayer(0)->getName()); EXPECT_EQ(QString("test"), layers2.getLayer(0)->getName());
CPPUNIT_ASSERT(&layers2 == layers2.getLayer(0)->getParent()); EXPECT_EQ(&layers2, layers2.getLayer(0)->getParent());
CPPUNIT_ASSERT(layers1.getLayer(0) != layers2.getLayer(0)); EXPECT_NE(layers1.getLayer(0), layers2.getLayer(0));
} }
void Layers_Test::testMaxLayerCount() TEST(Layers, maxLayerCount)
{ {
Layers layers1(NULL, _construc1); Layers layers1(NULL, _construc1);
layers1.setMaxLayerCount(2); layers1.setMaxLayerCount(2);
CPPUNIT_ASSERT_EQUAL(0, layers1.count()); EXPECT_EQ(0, layers1.count());
layers1.addLayer(); layers1.addLayer();
CPPUNIT_ASSERT_EQUAL(1, layers1.count()); EXPECT_EQ(1, layers1.count());
layers1.addLayer(); layers1.addLayer();
CPPUNIT_ASSERT_EQUAL(2, layers1.count()); EXPECT_EQ(2, layers1.count());
layers1.addLayer(); layers1.addLayer();
CPPUNIT_ASSERT_EQUAL(2, layers1.count()); EXPECT_EQ(2, layers1.count());
layers1.addLayer(); layers1.addLayer();
CPPUNIT_ASSERT_EQUAL(2, layers1.count()); EXPECT_EQ(2, layers1.count());
layers1.removeLayer(0); layers1.removeLayer(0);
CPPUNIT_ASSERT_EQUAL(1, layers1.count()); EXPECT_EQ(1, layers1.count());
layers1.addLayer(); layers1.addLayer();
CPPUNIT_ASSERT_EQUAL(2, layers1.count()); EXPECT_EQ(2, layers1.count());
layers1.addLayer(); layers1.addLayer();
CPPUNIT_ASSERT_EQUAL(2, layers1.count()); EXPECT_EQ(2, layers1.count());
} }
static int _legacy_instance_count = 0; static int _legacy_instance_count = 0;
@ -123,7 +124,7 @@ static void _legacy_copy(void* source, void* destination)
((LegacyData*)destination)->a = ((LegacyData*)source)->a; ((LegacyData*)destination)->a = ((LegacyData*)source)->a;
} }
void Layers_Test::testLegacyLayers() TEST(Layers, LegacyLayers)
{ {
LayerType type; LayerType type;
type.callback_create = _legacy_create; type.callback_create = _legacy_create;
@ -138,33 +139,31 @@ void Layers_Test::testLegacyLayers()
LegacyData* data1; LegacyData* data1;
// Test the null layer // Test the null layer
CPPUNIT_ASSERT_EQUAL(0, layersCount(layers1)); EXPECT_EQ(0, layersCount(layers1));
CPPUNIT_ASSERT_EQUAL(1, _legacy_instance_count); EXPECT_EQ(1, _legacy_instance_count);
data1 = (LegacyData*)layersGetLayer(layers1, 0); data1 = (LegacyData*)layersGetLayer(layers1, 0);
CPPUNIT_ASSERT_EQUAL(2, data1->a); EXPECT_EQ(2, data1->a);
data1->a = 3; data1->a = 3;
data1 = (LegacyData*)layersGetLayer(layers1, 0); data1 = (LegacyData*)layersGetLayer(layers1, 0);
CPPUNIT_ASSERT_EQUAL(3, data1->a); EXPECT_EQ(3, data1->a);
// Add an empty layer // Add an empty layer
layersAddLayer(layers1, NULL); layersAddLayer(layers1, NULL);
CPPUNIT_ASSERT_EQUAL(1, layersCount(layers1)); EXPECT_EQ(1, layersCount(layers1));
data1 = (LegacyData*)layersGetLayer(layers1, 0); data1 = (LegacyData*)layersGetLayer(layers1, 0);
CPPUNIT_ASSERT_EQUAL(2, data1->a); EXPECT_EQ(2, data1->a);
CPPUNIT_ASSERT_EQUAL(2, _legacy_instance_count); EXPECT_EQ(2, _legacy_instance_count);
// Validation // Validation
data1->a = 6; data1->a = 6;
layersValidate(layers1); layersValidate(layers1);
CPPUNIT_ASSERT_EQUAL(5, data1->a); EXPECT_EQ(5, data1->a);
// Naming // Naming
layersSetName(layers1, 0, "test1"); layersSetName(layers1, 0, "test1");
CPPUNIT_ASSERT(QString("test1") == QString(layersGetName(layers1, 0))); EXPECT_EQ(QString("test1"), QString(layersGetName(layers1, 0)));
// Deletion // Deletion
delete layers1; delete layers1;
CPPUNIT_ASSERT_EQUAL(0, _legacy_instance_count); EXPECT_EQ(0, _legacy_instance_count);
} }
CPPUNIT_TEST_SUITE_REGISTRATION(Layers_Test);

View file

@ -1,24 +0,0 @@
#ifndef LAYERS_TEST_H
#define LAYERS_TEST_H
#include "BaseTestCase.h"
class Layers_Test: public BaseTestCase
{
public:
CPPUNIT_TEST_SUITE(Layers_Test);
CPPUNIT_TEST(testConstructor);
CPPUNIT_TEST(testNullLayer);
CPPUNIT_TEST(testCopy);
CPPUNIT_TEST(testMaxLayerCount);
CPPUNIT_TEST(testLegacyLayers);
CPPUNIT_TEST_SUITE_END();
void testConstructor();
void testNullLayer();
void testCopy();
void testMaxLayerCount();
void testLegacyLayers();
};
#endif // LAYERS_TEST_H

View file

@ -0,0 +1,75 @@
#include "BaseTestCase.h"
#include "NoiseGenerator.h"
TEST(NoiseGenerator, getRange)
{
NoiseGenerator* noise;
double minvalue, maxvalue;
noise = new NoiseGenerator();
noise->addLevelSimple(0.1, -1.0, 1.0);
noise->addLevelSimple(0.2, -0.5, 0.2);
noise->addLevelSimple(0.4, -0.3, 1.2);
noise->validate();
noise->getRange(&minvalue, &maxvalue);
EXPECT_DOUBLE_EQ(minvalue, -1.8);
EXPECT_DOUBLE_EQ(maxvalue, 2.4);
delete noise;
}
TEST(NoiseGenerator, normalizeAmplitude)
{
int x;
NoiseGenerator* noise;
noise = new NoiseGenerator();
/* Symmetric case */
noise->addLevelsSimple(10, 1.0, -4.0, 4.0, 0.5);
noise->validate();
noise->normalizeAmplitude(-1.0, 1.0, 0);
for (x = 0; x < 1000; x++)
{
double value = noise->get1DTotal(0.01 * (double)x);
ASSERT_DOUBLE_IN_RANGE(value, -1.0, 1.0);
}
/* Target center differs from current center */
noise->clearLevels();
noise->addLevelsSimple(10, 1.0, -5.0, 5.0, 0.5);
noise->validate();
noise->normalizeAmplitude(0.0, 1.0, 0);
for (x = 0; x < 1000; x++)
{
double value = noise->get1DTotal(0.01 * (double)x);
ASSERT_DOUBLE_IN_RANGE(value, 0.0, 1.0);
}
/* Asymmetric range */
noise->clearLevels();
noise->addLevelsSimple(10, 1.0, 0.0, 10.0, 0.0);
noise->validate();
noise->normalizeAmplitude(0.0, 1.0, 0);
for (x = 0; x < 1000; x++)
{
double value = noise->get1DTotal(0.01 * (double)x);
ASSERT_DOUBLE_IN_RANGE(value, 0.0, 1.0);
}
/* Complex asymmetric case */
noise->clearLevels();
noise->addLevelsSimple(3, 1.0, -2.0, 8.0, 0.3);
noise->validate();
noise->normalizeAmplitude(-2.0, 4.0, 0.0);
for (x = 0; x < 1000; x++)
{
double value = noise->get1DTotal(0.01 * (double)x);
ASSERT_DOUBLE_IN_RANGE(value, -2.0, 4.0);
}
delete noise;
}

View file

@ -0,0 +1,51 @@
#include "BaseTestCase.h"
#include "PackStream.h"
TEST(PackStream, All)
{
PackStream* stream;
int i;
int data_i;
double data_d;
char* data_s;
char buffer[100];
/* Writing to pack */
stream = new PackStream();
stream->bindToFile("/tmp/test_paysages_pack", true);
for (i = 0; i < 5; i++)
{
data_i = i;
stream->write(&data_i);
data_d = (double)i;
stream->write(&data_d);
data_s = "Testing string 0123 (accentué) !";
stream->write(data_s, 100);
stream->write(data_s, 4);
stream->write(data_s, 5);
}
delete stream;
/* Reading from pack */
stream = new PackStream();
stream->bindToFile("/tmp/test_paysages_pack");
for (i = 0; i < 5; i++)
{
stream->read(&data_i);
ASSERT_EQ(i, data_i);
stream->read(&data_d);
ASSERT_DOUBLE_EQ((double)i, data_d);
stream->read(buffer, 100);
ASSERT_STREQ("Testing string 0123 (accentué) !", buffer);
stream->read(buffer, 4);
ASSERT_STREQ("Tes", buffer);
stream->read(buffer, 3);
ASSERT_STREQ("Te", buffer);
}
delete stream;
}

View file

@ -1,14 +1,12 @@
#include "testing/common.h" #include "BaseTestCase.h"
#include <math.h> #include <cmath>
#include "rendering/renderer.h" #include "renderer.h"
#include "rendering/tools.h" #include "camera.h"
#include "System.h"
static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* data) static Color _postProcessFragment(Renderer*, Vector3 location, void*)
{ {
UNUSED(renderer);
UNUSED(data);
/* Checker-board */ /* Checker-board */
double x = fmod(location.x, 0.2); double x = fmod(location.x, 0.2);
double z = fmod(location.z, 0.2); double z = fmod(location.z, 0.2);
@ -30,7 +28,7 @@ static Color _postProcessFragment(Renderer* renderer, Vector3 location, void* da
} }
} }
START_TEST(test_render_quad) TEST(Render, quad)
{ {
Color col; Color col;
Renderer* renderer = rendererCreate(); Renderer* renderer = rendererCreate();
@ -51,22 +49,18 @@ START_TEST(test_render_quad)
renderClear(renderer->render_area); renderClear(renderer->render_area);
renderer->pushQuad(renderer, v3(-1.0, 0.0, 1.0), v3(-1.0, 0.0, -1.0), v3(1.0, 0.0, -1.0), v3(1.0, 0.0, 1.0), _postProcessFragment, NULL); renderer->pushQuad(renderer, v3(-1.0, 0.0, 1.0), v3(-1.0, 0.0, -1.0), v3(1.0, 0.0, -1.0), v3(1.0, 0.0, 1.0), _postProcessFragment, NULL);
renderPostProcess(renderer->render_area, tests_cpu_count); renderPostProcess(renderer->render_area, System::getCoreCount());
col = renderGetPixel(renderer->render_area, 399, 599 - 435); col = renderGetPixel(renderer->render_area, 399, 599 - 435);
ck_assert_color_values(col, 1.0, 1.0, 1.0, 1.0); ASSERT_COLOR_RGBA(col, 1.0, 1.0, 1.0, 1.0);
col = renderGetPixel(renderer->render_area, 399, 599 - 436); col = renderGetPixel(renderer->render_area, 399, 599 - 436);
ck_assert_color_values(col, 0.0, 0.0, 0.0, 1.0); ASSERT_COLOR_RGBA(col, 0.0, 0.0, 0.0, 1.0);
col = renderGetPixel(renderer->render_area, 400, 599 - 435); col = renderGetPixel(renderer->render_area, 400, 599 - 435);
ck_assert_color_values(col, 0.0, 0.0, 0.0, 1.0); ASSERT_COLOR_RGBA(col, 0.0, 0.0, 0.0, 1.0);
col = renderGetPixel(renderer->render_area, 400, 599 - 436); col = renderGetPixel(renderer->render_area, 400, 599 - 436);
ck_assert_color_values(col, 1.0, 1.0, 1.0, 1.0); ASSERT_COLOR_RGBA(col, 1.0, 1.0, 1.0, 1.0);
renderSaveToFile(renderer->render_area, "./output/test_render_quad.png"); renderSaveToFile(renderer->render_area, "./output/test_render_quad.png");
rendererDelete(renderer); rendererDelete(renderer);
} }
END_TEST
TEST_CASE(render, test_render_quad)

View file

@ -0,0 +1,219 @@
#include "BaseTestCase.h"
#include <cmath>
#include "NoiseGenerator.h"
#include "terrain/public.h"
/* Noise sin period is defined at 20.0 */
#define X_FACTOR (M_PI / 10.0)
static double _noise1dMock(double x)
{
return sin(x * X_FACTOR) * 0.5 + 0.5;
}
static double _noise2dMock(double x, double)
{
return sin(x * X_FACTOR) * 0.5 + 0.5;
}
static double _noise3dMock(double x, double, double)
{
return sin(x * X_FACTOR) * 0.5 + 0.5;
}
class TerrainPainting_Test : public BaseTestCase {
protected:
virtual void SetUp() {
terrain = (TerrainDefinition*)TerrainDefinitionClass.create();
terrain->height = 3.0;
terrain->scaling = 1.0;
terrain->_height_noise->clearLevels();
NoiseLevel level = {1.0, 2.0, -1.0, 0.0, 0.0, 0.0};
terrain->_height_noise->addLevel(level, 0);
terrain->_height_noise->setCustomFunction(_noise1dMock, _noise2dMock, _noise3dMock);
}
virtual void TearDown()
{
TerrainDefinitionClass.destroy(terrain);
}
TerrainDefinition* terrain;
};
TEST_F(TerrainPainting_Test, grid)
{
/* Test base grid */
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 0, 0));
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 1, 0));
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 0, 0, 1));
EXPECT_DOUBLE_EQ(sin(1.0 * X_FACTOR), terrainGetGridHeight(terrain, 1, 0, 0));
EXPECT_DOUBLE_EQ(sin(2.0 * X_FACTOR), terrainGetGridHeight(terrain, 2, 0, 0));
EXPECT_DOUBLE_EQ(sin(3.0 * X_FACTOR), terrainGetGridHeight(terrain, 3, 0, 0));
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrainGetGridHeight(terrain, 4, 0, 0));
EXPECT_DOUBLE_EQ(1.0, terrainGetGridHeight(terrain, 5, 0, 0));
EXPECT_DOUBLE_EQ(sin(4.0 * X_FACTOR), terrainGetGridHeight(terrain, 6, 0, 0));
EXPECT_DOUBLE_EQ(-sin(1.0 * X_FACTOR), terrainGetGridHeight(terrain, -1, 0, 0));
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 10, 0, 0));
EXPECT_DOUBLE_EQ(-1.0, terrainGetGridHeight(terrain, 15, 0, 0));
EXPECT_DOUBLE_EQ(0.0, terrainGetGridHeight(terrain, 20, 0, 0));
EXPECT_DOUBLE_EQ(-1.0, terrainGetGridHeight(terrain, -5, 0, 0));
/* Test interpolated result */
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0.0, 0.0, 0, 0), 0.0);
EXPECT_DOUBLE_IN_RANGE(terrainGetInterpolatedHeight(terrain, 0.5, 0.0, 0, 0), 0.1564, 0.1566);
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1.0, 0.0, 0, 0), sin(1.0 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0.0, 0.0, 1, 0), 0.0);
EXPECT_DOUBLE_IN_RANGE(terrainGetInterpolatedHeight(terrain, 0.5, 0.0, 1, 0), 3.0 * 0.1564, 3.0 * 0.1566);
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1.0, 0.0, 1, 0), 3.0 * sin(1.0 * X_FACTOR));
/* Test scaling */
terrain->scaling = 2.0;
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 0, 0, 0), 0.0);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 1, 0, 0), sin(1.0 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 2, 0, 0), sin(2.0 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 3, 0, 0), sin(3.0 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0, 0, 0, 0), 0.0);
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1, 0, 0, 0), sin(0.5 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 2, 0, 0, 0), sin(1.0 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 3, 0, 0, 0), sin(1.5 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 0, 0, 1, 0), 0.0);
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 1, 0, 1, 0), 6.0 * sin(0.5 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 2, 0, 1, 0), 6.0 * sin(1.0 * X_FACTOR));
EXPECT_DOUBLE_EQ(terrainGetInterpolatedHeight(terrain, 3, 0, 1, 0), 6.0 * sin(1.5 * X_FACTOR));
}
static void _checkBrushResultSides(TerrainDefinition* terrain, TerrainBrush*, double center, double midhard, double hard, double midsoft, double soft, double exter, double neg_midhard, double neg_hard, double neg_midsoft, double neg_soft, double neg_exter)
{
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 0, 0, 1), center);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 1, 0, 1), midhard);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 2, 0, 1), hard);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 3, 0, 1), midsoft);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 4, 0, 1), soft);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, 5, 0, 1), exter);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -1, 0, 1), neg_midhard);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -2, 0, 1), neg_hard);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -3, 0, 1), neg_midsoft);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -4, 0, 1), neg_soft);
EXPECT_DOUBLE_EQ(terrainGetGridHeight(terrain, -5, 0, 1), neg_exter);
}
static void _checkBrushResult(TerrainDefinition* terrain, TerrainBrush* brush, double center, double midhard, double hard, double midsoft, double soft, double exter, int mirror)
{
if (mirror)
{
_checkBrushResultSides(terrain, brush, center, midhard, hard, midsoft, soft, exter, -midhard, -hard, -midsoft, -soft, -exter);
}
else
{
_checkBrushResultSides(terrain, brush, center, midhard, hard, midsoft, soft, exter, midhard, hard, midsoft, soft, exter);
}
}
TEST_F(TerrainPainting_Test, brush_flatten)
{
/* Set up */
TerrainBrush brush = {0.0, 0.0, 2.0, 2.0, 4.0};
terrain->height = 1.0;
terrain->scaling = 1.0;
terrain->_height_noise->forceValue(0.0);
/* Test flattening center at 0.5 */
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 1.0);
_checkBrushResult(terrain, &brush, 0.5, 0.5, 0.5, 0.25, 0.0, 0.0, 0);
/* Test brush strength */
terrainClearPainting(terrain->height_map);
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 0.01);
_checkBrushResult(terrain, &brush, 0.005, 0.005, 0.005, 0.0025, 0.0, 0.0, 0);
/* Test cumulative effect */
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 0.01);
_checkBrushResult(terrain, &brush, 0.00995, 0.00995, 0.00995, 0.0049875, 0.0, 0.0, 0);
/* Test with height modifier */
terrain->height = 10.0;
terrainClearPainting(terrain->height_map);
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 1.0);
_checkBrushResult(terrain, &brush, 0.05, 0.05, 0.05, 0.025, 0.0, 0.0, 0);
/* Test with scaling modifier */
terrain->height = 10.0;
terrain->scaling = 2.0;
terrainClearPainting(terrain->height_map);
_checkBrushResult(terrain, &brush, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0);
terrainBrushFlatten(terrain->height_map, &brush, 0.5, 1.0);
_checkBrushResult(terrain, &brush, 0.05, 0.05, 0.05, 0.025, 0.0, 0.0, 0);
}
TEST_F(TerrainPainting_Test, brush_reset)
{
/* Set up */
TerrainBrush brush = {0.0, 0.0, 2.0, 2.0, 4.0};
TerrainBrush brush_full = {0.0, 0.0, 4.0, 0.0, 4.0};
terrain->height = 1.0;
terrain->scaling = 1.0;
terrain->_height_noise->forceValue(1.0);
/* Test resetting at center */
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
_checkBrushResult(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 0);
terrainBrushReset(terrain->height_map, &brush, 1.0);
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.5, 2.0, 1.0, 0);
/* Test brush strength */
terrainClearPainting(terrain->height_map);
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
_checkBrushResult(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 0);
terrainBrushReset(terrain->height_map, &brush, 0.1);
_checkBrushResult(terrain, &brush, 1.9, 1.9, 1.9, 1.95, 2.0, 1.0, 0);
/* Test cumulative effect */
terrainBrushReset(terrain->height_map, &brush, 0.1);
_checkBrushResult(terrain, &brush, 1.81, 1.81, 1.81, 1.9025, 2.0, 1.0, 0);
/* Test with height modifier */
terrain->height = 10.0;
terrainClearPainting(terrain->height_map);
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
_checkBrushResult(terrain, &brush, 1.1, 1.1, 1.1, 1.1, 1.1, 1.0, 0);
terrainBrushReset(terrain->height_map, &brush, 0.1);
_checkBrushResult(terrain, &brush, 1.099, 1.099, 1.099, 1.0995, 1.1, 1.0, 0);
/* Test with scaling modifier */
terrain->height = 10.0;
terrain->scaling = 2.0;
terrainClearPainting(terrain->height_map);
_checkBrushResult(terrain, &brush, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0);
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
_checkBrushResult(terrain, &brush, 1.1, 1.1, 1.1, 1.1, 1.1, 1.0, 0);
terrainBrushReset(terrain->height_map, &brush, 0.1);
_checkBrushResult(terrain, &brush, 1.099, 1.099, 1.099, 1.0995, 1.1, 1.0, 0);
}
TEST_F(TerrainPainting_Test, brush_reset_basevalue)
{
/* Set up */
TerrainBrush brush = {0.0, 0.0, 2.0, 2.0, 4.0};
TerrainBrush brush_full = {0.0, 0.0, 4.0, 0.0, 4.0};
terrain->height = 1.0;
terrain->scaling = 1.0;
/* Test with scaling and the sinusoid setup (to test the basevalue sampling) */
terrain->height = 1.0;
terrain->scaling = 2.0;
_checkBrushResult(terrain, &brush, 0.0, 0.309016994375, 0.587785252292, 0.809016994375, 0.951056516295, 1.0, 1);
terrainBrushFlatten(terrain->height_map, &brush_full, 2.0, 1.0);
_checkBrushResultSides(terrain, &brush, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 2.0, -1.0);
terrainBrushReset(terrain->height_map, &brush, 1.0);
_checkBrushResultSides(terrain, &brush, 0.0, 0.309016994375, 0.587785252292, 2.0 - (2.0 - 0.809016994375) * 0.5, 2.0, 1.0, -0.309016994375, -0.587785252292, 2.0 - (2.0 + 0.809016994375) * 0.5, 2.0, -1.0);
}

56
src/tests/Zone_Test.cpp Normal file
View file

@ -0,0 +1,56 @@
#include "BaseTestCase.h"
#include "tools/zone.h"
class Zone_Test : public BaseTestCase {
protected:
virtual void SetUp() {
zone = zoneCreate();
}
virtual void TearDown()
{
zoneDelete(zone);
}
Zone* zone;
};
TEST_F(Zone_Test, absolute_height)
{
zoneAddHeightRangeQuick(zone, 1.0, -1.0, 2.0, 5.0, 6.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -10.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -2.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -1.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -0.5, 0.0), VECTOR_UP), 1.0 / 6.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 0.0, 0.0), VECTOR_UP), 1.0 / 3.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 0.5, 0.0), VECTOR_UP), 0.5);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 2.0, 0.0), VECTOR_UP), 1.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 2.1, 0.0), VECTOR_UP), 1.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 3.5, 0.0), VECTOR_UP), 1.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 4.9, 0.0), VECTOR_UP), 1.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 5.0, 0.0), VECTOR_UP), 1.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 5.2, 0.0), VECTOR_UP), 0.8);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 5.7, 0.0), VECTOR_UP), 0.3);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 6.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 15.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 150.0, 0.0), VECTOR_UP), 0.0);
}
TEST_F(Zone_Test, relative_height)
{
zoneAddHeightRangeQuick(zone, 1.0, 0.2, 0.3, 0.6, 0.9);
zoneSetRelativeHeight(zone, -2.0, 2.0, 8.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -10.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -2.1, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -2.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -1.0, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -0.5, 0.0), VECTOR_UP), 0.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, -0.2, 0.0), VECTOR_UP), 0.25);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 0.0, 0.0), VECTOR_UP), 0.5);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 0.3, 0.0), VECTOR_UP), 0.875);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 0.5, 0.0), VECTOR_UP), 1.0);
EXPECT_DOUBLE_EQ(zoneGetValue(zone, v3(0.0, 1.0, 0.0), VECTOR_UP), 1.0);
}

View file

@ -0,0 +1,157 @@
Changes for 1.7.0:
* New feature: death tests are supported on OpenBSD and in iOS
simulator now.
* New feature: Google Test now implements a protocol to allow
a test runner to detect that a test program has exited
prematurely and report it as a failure (before it would be
falsely reported as a success if the exit code is 0).
* New feature: Test::RecordProperty() can now be used outside of the
lifespan of a test method, in which case it will be attributed to
the current test case or the test program in the XML report.
* New feature (potentially breaking): --gtest_list_tests now prints
the type parameters and value parameters for each test.
* Improvement: char pointers and char arrays are now escaped properly
in failure messages.
* Improvement: failure summary in XML reports now includes file and
line information.
* Improvement: the <testsuites> XML element now has a timestamp attribute.
* Improvement: When --gtest_filter is specified, XML report now doesn't
contain information about tests that are filtered out.
* Fixed the bug where long --gtest_filter flag values are truncated in
death tests.
* Potentially breaking change: RUN_ALL_TESTS() is now implemented as a
function instead of a macro in order to work better with Clang.
* Compatibility fixes with C++ 11 and various platforms.
* Bug/warning fixes.
Changes for 1.6.0:
* New feature: ADD_FAILURE_AT() for reporting a test failure at the
given source location -- useful for writing testing utilities.
* New feature: the universal value printer is moved from Google Mock
to Google Test.
* New feature: type parameters and value parameters are reported in
the XML report now.
* A gtest_disable_pthreads CMake option.
* Colored output works in GNU Screen sessions now.
* Parameters of value-parameterized tests are now printed in the
textual output.
* Failures from ad hoc test assertions run before RUN_ALL_TESTS() are
now correctly reported.
* Arguments of ASSERT_XY and EXPECT_XY no longer need to support << to
ostream.
* More complete handling of exceptions.
* GTEST_ASSERT_XY can be used instead of ASSERT_XY in case the latter
name is already used by another library.
* --gtest_catch_exceptions is now true by default, allowing a test
program to continue after an exception is thrown.
* Value-parameterized test fixtures can now derive from Test and
WithParamInterface<T> separately, easing conversion of legacy tests.
* Death test messages are clearly marked to make them more
distinguishable from other messages.
* Compatibility fixes for Android, Google Native Client, MinGW, HP UX,
PowerPC, Lucid autotools, libCStd, Sun C++, Borland C++ Builder (Code Gear),
IBM XL C++ (Visual Age C++), and C++0x.
* Bug fixes and implementation clean-ups.
* Potentially incompatible changes: disables the harmful 'make install'
command in autotools.
Changes for 1.5.0:
* New feature: assertions can be safely called in multiple threads
where the pthreads library is available.
* New feature: predicates used inside EXPECT_TRUE() and friends
can now generate custom failure messages.
* New feature: Google Test can now be compiled as a DLL.
* New feature: fused source files are included.
* New feature: prints help when encountering unrecognized Google Test flags.
* Experimental feature: CMake build script (requires CMake 2.6.4+).
* Experimental feature: the Pump script for meta programming.
* double values streamed to an assertion are printed with enough precision
to differentiate any two different values.
* Google Test now works on Solaris and AIX.
* Build and test script improvements.
* Bug fixes and implementation clean-ups.
Potentially breaking changes:
* Stopped supporting VC++ 7.1 with exceptions disabled.
* Dropped support for 'make install'.
Changes for 1.4.0:
* New feature: the event listener API
* New feature: test shuffling
* New feature: the XML report format is closer to junitreport and can
be parsed by Hudson now.
* New feature: when a test runs under Visual Studio, its failures are
integrated in the IDE.
* New feature: /MD(d) versions of VC++ projects.
* New feature: elapsed time for the tests is printed by default.
* New feature: comes with a TR1 tuple implementation such that Boost
is no longer needed for Combine().
* New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends.
* New feature: the Xcode project can now produce static gtest
libraries in addition to a framework.
* Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile,
Symbian, gcc, and C++Builder.
* Bug fixes and implementation clean-ups.
Changes for 1.3.0:
* New feature: death tests on Windows, Cygwin, and Mac.
* New feature: ability to use Google Test assertions in other testing
frameworks.
* New feature: ability to run disabled test via
--gtest_also_run_disabled_tests.
* New feature: the --help flag for printing the usage.
* New feature: access to Google Test flag values in user code.
* New feature: a script that packs Google Test into one .h and one
.cc file for easy deployment.
* New feature: support for distributing test functions to multiple
machines (requires support from the test runner).
* Bug fixes and implementation clean-ups.
Changes for 1.2.1:
* Compatibility fixes for Linux IA-64 and IBM z/OS.
* Added support for using Boost and other TR1 implementations.
* Changes to the build scripts to support upcoming release of Google C++
Mocking Framework.
* Added Makefile to the distribution package.
* Improved build instructions in README.
Changes for 1.2.0:
* New feature: value-parameterized tests.
* New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS)
macros.
* Changed the XML report format to match JUnit/Ant's.
* Added tests to the Xcode project.
* Added scons/SConscript for building with SCons.
* Added src/gtest-all.cc for building Google Test from a single file.
* Fixed compatibility with Solaris and z/OS.
* Enabled running Python tests on systems with python 2.3 installed,
e.g. Mac OS X 10.4.
* Bug fixes.
Changes for 1.1.0:
* New feature: type-parameterized tests.
* New feature: exception assertions.
* New feature: printing elapsed time of tests.
* Improved the robustness of death tests.
* Added an Xcode project and samples.
* Adjusted the output format on Windows to be understandable by Visual Studio.
* Minor bug fixes.
Changes for 1.0.1:
* Added project files for Visual Studio 7.1.
* Fixed issues with compiling on Mac OS X.
* Fixed issues with compiling on Cygwin.
Changes for 1.0.0:
* Initial Open Source release of Google Test

View file

@ -0,0 +1,252 @@
########################################################################
# CMake build script for Google Test.
#
# To run the tests for Google Test itself on Linux, use 'make test' or
# ctest. You can select which tests to run using 'ctest -R regex'.
# For more options, run 'ctest --help'.
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to
# make it prominent in the GUI.
option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF)
# When other libraries are using a shared version of runtime libraries,
# Google Test also has to use one.
option(
gtest_force_shared_crt
"Use shared (DLL) run-time lib even when Google Test is built as static lib."
OFF)
option(gtest_build_tests "Build all of gtest's own tests." OFF)
option(gtest_build_samples "Build gtest's sample programs." OFF)
option(gtest_disable_pthreads "Disable uses of pthreads in gtest." OFF)
# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build().
include(cmake/hermetic_build.cmake OPTIONAL)
if (COMMAND pre_project_set_up_hermetic_build)
pre_project_set_up_hermetic_build()
endif()
########################################################################
#
# Project-wide settings
# Name of the project.
#
# CMake files in this project can refer to the root source directory
# as ${gtest_SOURCE_DIR} and to the root binary directory as
# ${gtest_BINARY_DIR}.
# Language "C" is required for find_package(Threads).
project(gtest CXX C)
cmake_minimum_required(VERSION 2.6.2)
if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
endif()
# Define helper functions and macros used by Google Test.
include(cmake/internal_utils.cmake)
config_compiler_and_linker() # Defined in internal_utils.cmake.
# Where Google Test's .h files can be found.
include_directories(
${gtest_SOURCE_DIR}/include
${gtest_SOURCE_DIR})
# Where Google Test's libraries can be found.
link_directories(${gtest_BINARY_DIR}/src)
########################################################################
#
# Defines the gtest & gtest_main libraries. User tests should link
# with one of them.
# Google Test libraries. We build them using more strict warnings than what
# are used for other targets, to ensure that gtest can be compiled by a user
# aggressive about warnings.
cxx_library(gtest "${cxx_strict}" src/gtest-all.cc)
cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
target_link_libraries(gtest_main gtest)
########################################################################
#
# Samples on how to link user tests with gtest or gtest_main.
#
# They are not built by default. To build them, set the
# gtest_build_samples option to ON. You can do it by running ccmake
# or specifying the -Dgtest_build_samples=ON flag when running cmake.
if (gtest_build_samples)
cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)
cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)
cxx_executable(sample3_unittest samples gtest_main)
cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)
cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)
cxx_executable(sample6_unittest samples gtest_main)
cxx_executable(sample7_unittest samples gtest_main)
cxx_executable(sample8_unittest samples gtest_main)
cxx_executable(sample9_unittest samples gtest)
cxx_executable(sample10_unittest samples gtest)
endif()
########################################################################
#
# Google Test's own tests.
#
# You can skip this section if you aren't interested in testing
# Google Test itself.
#
# The tests are not built by default. To build them, set the
# gtest_build_tests option to ON. You can do it by running ccmake
# or specifying the -Dgtest_build_tests=ON flag when running cmake.
if (gtest_build_tests)
# This must be set in the root directory for the tests to be run by
# 'make test' or ctest.
enable_testing()
############################################################
# C++ tests built with standard compiler flags.
cxx_test(gtest-death-test_test gtest_main)
cxx_test(gtest_environment_test gtest)
cxx_test(gtest-filepath_test gtest_main)
cxx_test(gtest-linked_ptr_test gtest_main)
cxx_test(gtest-listener_test gtest_main)
cxx_test(gtest_main_unittest gtest_main)
cxx_test(gtest-message_test gtest_main)
cxx_test(gtest_no_test_unittest gtest)
cxx_test(gtest-options_test gtest_main)
cxx_test(gtest-param-test_test gtest
test/gtest-param-test2_test.cc)
cxx_test(gtest-port_test gtest_main)
cxx_test(gtest_pred_impl_unittest gtest_main)
cxx_test(gtest_premature_exit_test gtest
test/gtest_premature_exit_test.cc)
cxx_test(gtest-printers_test gtest_main)
cxx_test(gtest_prod_test gtest_main
test/production.cc)
cxx_test(gtest_repeat_test gtest)
cxx_test(gtest_sole_header_test gtest_main)
cxx_test(gtest_stress_test gtest)
cxx_test(gtest-test-part_test gtest_main)
cxx_test(gtest_throw_on_failure_ex_test gtest)
cxx_test(gtest-typed-test_test gtest_main
test/gtest-typed-test2_test.cc)
cxx_test(gtest_unittest gtest_main)
cxx_test(gtest-unittest-api_test gtest)
############################################################
# C++ tests built with non-standard compiler flags.
# MSVC 7.1 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310)
cxx_library(gtest_no_exception "${cxx_no_exception}"
src/gtest-all.cc)
cxx_library(gtest_main_no_exception "${cxx_no_exception}"
src/gtest-all.cc src/gtest_main.cc)
endif()
cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
src/gtest-all.cc src/gtest_main.cc)
cxx_test_with_flags(gtest-death-test_ex_nocatch_test
"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=0"
gtest test/gtest-death-test_ex_test.cc)
cxx_test_with_flags(gtest-death-test_ex_catch_test
"${cxx_exception} -DGTEST_ENABLE_CATCH_EXCEPTIONS_=1"
gtest test/gtest-death-test_ex_test.cc)
cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
gtest_main_no_rtti test/gtest_unittest.cc)
cxx_shared_library(gtest_dll "${cxx_default}"
src/gtest-all.cc src/gtest_main.cc)
cxx_executable_with_flags(gtest_dll_test_ "${cxx_default}"
gtest_dll test/gtest_all_test.cc)
set_target_properties(gtest_dll_test_
PROPERTIES
COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
if (NOT MSVC OR NOT MSVC_VERSION EQUAL 1600)
# The C++ Standard specifies tuple_element<int, class>.
# Yet MSVC 10's <utility> declares tuple_element<size_t, class>.
# That declaration conflicts with our own standard-conforming
# tuple implementation. Therefore using our own tuple with
# MSVC 10 doesn't compile.
cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}"
src/gtest-all.cc src/gtest_main.cc)
cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}"
gtest_main_use_own_tuple test/gtest-tuple_test.cc)
cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}"
gtest_main_use_own_tuple
test/gtest-param-test_test.cc test/gtest-param-test2_test.cc)
endif()
############################################################
# Python tests.
cxx_executable(gtest_break_on_failure_unittest_ test gtest)
py_test(gtest_break_on_failure_unittest)
# MSVC 7.1 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310)
cxx_executable_with_flags(
gtest_catch_exceptions_no_ex_test_
"${cxx_no_exception}"
gtest_main_no_exception
test/gtest_catch_exceptions_test_.cc)
endif()
cxx_executable_with_flags(
gtest_catch_exceptions_ex_test_
"${cxx_exception}"
gtest_main
test/gtest_catch_exceptions_test_.cc)
py_test(gtest_catch_exceptions_test)
cxx_executable(gtest_color_test_ test gtest)
py_test(gtest_color_test)
cxx_executable(gtest_env_var_test_ test gtest)
py_test(gtest_env_var_test)
cxx_executable(gtest_filter_unittest_ test gtest)
py_test(gtest_filter_unittest)
cxx_executable(gtest_help_test_ test gtest_main)
py_test(gtest_help_test)
cxx_executable(gtest_list_tests_unittest_ test gtest)
py_test(gtest_list_tests_unittest)
cxx_executable(gtest_output_test_ test gtest)
py_test(gtest_output_test)
cxx_executable(gtest_shuffle_test_ test gtest)
py_test(gtest_shuffle_test)
# MSVC 7.1 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310)
cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception)
set_target_properties(gtest_throw_on_failure_test_
PROPERTIES
COMPILE_FLAGS "${cxx_no_exception}")
py_test(gtest_throw_on_failure_test)
endif()
cxx_executable(gtest_uninitialized_test_ test gtest)
py_test(gtest_uninitialized_test)
cxx_executable(gtest_xml_outfile1_test_ test gtest_main)
cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
py_test(gtest_xml_outfiles_test)
cxx_executable(gtest_xml_output_unittest_ test gtest)
py_test(gtest_xml_output_unittest)
endif()

View file

@ -0,0 +1,37 @@
# This file contains a list of people who've made non-trivial
# contribution to the Google C++ Testing Framework project. People
# who commit code to the project are encouraged to add their names
# here. Please keep the list sorted by first names.
Ajay Joshi <jaj@google.com>
Balázs Dán <balazs.dan@gmail.com>
Bharat Mediratta <bharat@menalto.com>
Chandler Carruth <chandlerc@google.com>
Chris Prince <cprince@google.com>
Chris Taylor <taylorc@google.com>
Dan Egnor <egnor@google.com>
Eric Roman <eroman@chromium.org>
Hady Zalek <hady.zalek@gmail.com>
Jeffrey Yasskin <jyasskin@google.com>
Jói Sigurðsson <joi@google.com>
Keir Mierle <mierle@gmail.com>
Keith Ray <keith.ray@gmail.com>
Kenton Varda <kenton@google.com>
Manuel Klimek <klimek@google.com>
Markus Heule <markus.heule@gmail.com>
Mika Raento <mikie@iki.fi>
Miklós Fazekas <mfazekas@szemafor.com>
Pasi Valminen <pasi.valminen@gmail.com>
Patrick Hanna <phanna@google.com>
Patrick Riley <pfr@google.com>
Peter Kaminski <piotrk@google.com>
Preston Jackson <preston.a.jackson@gmail.com>
Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.com>
Russ Cox <rsc@google.com>
Russ Rufer <russ@pentad.com>
Sean Mcafee <eefacm@gmail.com>
Sigurður Ásgeirsson <siggi@google.com>
Tracy Bialik <tracy@pentad.com>
Vadim Berman <vadimb@google.com>
Vlad Losev <vladl@google.com>
Zhanyong Wan <wan@google.com>

View file

@ -0,0 +1,28 @@
Copyright 2008, Google Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,306 @@
# Automake file
ACLOCAL_AMFLAGS = -I m4
# Nonstandard package files for distribution
EXTRA_DIST = \
CHANGES \
CONTRIBUTORS \
LICENSE \
include/gtest/gtest-param-test.h.pump \
include/gtest/internal/gtest-param-util-generated.h.pump \
include/gtest/internal/gtest-tuple.h.pump \
include/gtest/internal/gtest-type-util.h.pump \
make/Makefile \
scripts/fuse_gtest_files.py \
scripts/gen_gtest_pred_impl.py \
scripts/pump.py \
scripts/test/Makefile
# gtest source files that we don't compile directly. They are
# #included by gtest-all.cc.
GTEST_SRC = \
src/gtest-death-test.cc \
src/gtest-filepath.cc \
src/gtest-internal-inl.h \
src/gtest-port.cc \
src/gtest-printers.cc \
src/gtest-test-part.cc \
src/gtest-typed-test.cc \
src/gtest.cc
EXTRA_DIST += $(GTEST_SRC)
# Sample files that we don't compile.
EXTRA_DIST += \
samples/prime_tables.h \
samples/sample2_unittest.cc \
samples/sample3_unittest.cc \
samples/sample4_unittest.cc \
samples/sample5_unittest.cc \
samples/sample6_unittest.cc \
samples/sample7_unittest.cc \
samples/sample8_unittest.cc \
samples/sample9_unittest.cc
# C++ test files that we don't compile directly.
EXTRA_DIST += \
test/gtest-death-test_ex_test.cc \
test/gtest-death-test_test.cc \
test/gtest-filepath_test.cc \
test/gtest-linked_ptr_test.cc \
test/gtest-listener_test.cc \
test/gtest-message_test.cc \
test/gtest-options_test.cc \
test/gtest-param-test2_test.cc \
test/gtest-param-test2_test.cc \
test/gtest-param-test_test.cc \
test/gtest-param-test_test.cc \
test/gtest-param-test_test.h \
test/gtest-port_test.cc \
test/gtest_premature_exit_test.cc \
test/gtest-printers_test.cc \
test/gtest-test-part_test.cc \
test/gtest-tuple_test.cc \
test/gtest-typed-test2_test.cc \
test/gtest-typed-test_test.cc \
test/gtest-typed-test_test.h \
test/gtest-unittest-api_test.cc \
test/gtest_break_on_failure_unittest_.cc \
test/gtest_catch_exceptions_test_.cc \
test/gtest_color_test_.cc \
test/gtest_env_var_test_.cc \
test/gtest_environment_test.cc \
test/gtest_filter_unittest_.cc \
test/gtest_help_test_.cc \
test/gtest_list_tests_unittest_.cc \
test/gtest_main_unittest.cc \
test/gtest_no_test_unittest.cc \
test/gtest_output_test_.cc \
test/gtest_pred_impl_unittest.cc \
test/gtest_prod_test.cc \
test/gtest_repeat_test.cc \
test/gtest_shuffle_test_.cc \
test/gtest_sole_header_test.cc \
test/gtest_stress_test.cc \
test/gtest_throw_on_failure_ex_test.cc \
test/gtest_throw_on_failure_test_.cc \
test/gtest_uninitialized_test_.cc \
test/gtest_unittest.cc \
test/gtest_unittest.cc \
test/gtest_xml_outfile1_test_.cc \
test/gtest_xml_outfile2_test_.cc \
test/gtest_xml_output_unittest_.cc \
test/production.cc \
test/production.h
# Python tests that we don't run.
EXTRA_DIST += \
test/gtest_break_on_failure_unittest.py \
test/gtest_catch_exceptions_test.py \
test/gtest_color_test.py \
test/gtest_env_var_test.py \
test/gtest_filter_unittest.py \
test/gtest_help_test.py \
test/gtest_list_tests_unittest.py \
test/gtest_output_test.py \
test/gtest_output_test_golden_lin.txt \
test/gtest_shuffle_test.py \
test/gtest_test_utils.py \
test/gtest_throw_on_failure_test.py \
test/gtest_uninitialized_test.py \
test/gtest_xml_outfiles_test.py \
test/gtest_xml_output_unittest.py \
test/gtest_xml_test_utils.py
# CMake script
EXTRA_DIST += \
CMakeLists.txt \
cmake/internal_utils.cmake
# MSVC project files
EXTRA_DIST += \
msvc/gtest-md.sln \
msvc/gtest-md.vcproj \
msvc/gtest.sln \
msvc/gtest.vcproj \
msvc/gtest_main-md.vcproj \
msvc/gtest_main.vcproj \
msvc/gtest_prod_test-md.vcproj \
msvc/gtest_prod_test.vcproj \
msvc/gtest_unittest-md.vcproj \
msvc/gtest_unittest.vcproj
# xcode project files
EXTRA_DIST += \
xcode/Config/DebugProject.xcconfig \
xcode/Config/FrameworkTarget.xcconfig \
xcode/Config/General.xcconfig \
xcode/Config/ReleaseProject.xcconfig \
xcode/Config/StaticLibraryTarget.xcconfig \
xcode/Config/TestTarget.xcconfig \
xcode/Resources/Info.plist \
xcode/Scripts/runtests.sh \
xcode/Scripts/versiongenerate.py \
xcode/gtest.xcodeproj/project.pbxproj
# xcode sample files
EXTRA_DIST += \
xcode/Samples/FrameworkSample/Info.plist \
xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \
xcode/Samples/FrameworkSample/runtests.sh \
xcode/Samples/FrameworkSample/widget.cc \
xcode/Samples/FrameworkSample/widget.h \
xcode/Samples/FrameworkSample/widget_test.cc
# C++Builder project files
EXTRA_DIST += \
codegear/gtest.cbproj \
codegear/gtest.groupproj \
codegear/gtest_all.cc \
codegear/gtest_link.cc \
codegear/gtest_main.cbproj \
codegear/gtest_unittest.cbproj
# Distribute and install M4 macro
m4datadir = $(datadir)/aclocal
m4data_DATA = m4/gtest.m4
EXTRA_DIST += $(m4data_DATA)
# We define the global AM_CPPFLAGS as everything we compile includes from these
# directories.
AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include
# Modifies compiler and linker flags for pthreads compatibility.
if HAVE_PTHREADS
AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
AM_LIBS = @PTHREAD_LIBS@
else
AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
endif
# Build rules for libraries.
lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la
lib_libgtest_la_SOURCES = src/gtest-all.cc
pkginclude_HEADERS = \
include/gtest/gtest-death-test.h \
include/gtest/gtest-message.h \
include/gtest/gtest-param-test.h \
include/gtest/gtest-printers.h \
include/gtest/gtest-spi.h \
include/gtest/gtest-test-part.h \
include/gtest/gtest-typed-test.h \
include/gtest/gtest.h \
include/gtest/gtest_pred_impl.h \
include/gtest/gtest_prod.h
pkginclude_internaldir = $(pkgincludedir)/internal
pkginclude_internal_HEADERS = \
include/gtest/internal/gtest-death-test-internal.h \
include/gtest/internal/gtest-filepath.h \
include/gtest/internal/gtest-internal.h \
include/gtest/internal/gtest-linked_ptr.h \
include/gtest/internal/gtest-param-util-generated.h \
include/gtest/internal/gtest-param-util.h \
include/gtest/internal/gtest-port.h \
include/gtest/internal/gtest-string.h \
include/gtest/internal/gtest-tuple.h \
include/gtest/internal/gtest-type-util.h
lib_libgtest_main_la_SOURCES = src/gtest_main.cc
lib_libgtest_main_la_LIBADD = lib/libgtest.la
# Bulid rules for samples and tests. Automake's naming for some of
# these variables isn't terribly obvious, so this is a brief
# reference:
#
# TESTS -- Programs run automatically by "make check"
# check_PROGRAMS -- Programs built by "make check" but not necessarily run
noinst_LTLIBRARIES = samples/libsamples.la
samples_libsamples_la_SOURCES = \
samples/sample1.cc \
samples/sample1.h \
samples/sample2.cc \
samples/sample2.h \
samples/sample3-inl.h \
samples/sample4.cc \
samples/sample4.h
TESTS=
TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
GTEST_BUILD_DIR="$(top_builddir)/test"
check_PROGRAMS=
# A simple sample on using gtest.
TESTS += samples/sample1_unittest
check_PROGRAMS += samples/sample1_unittest
samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc
samples_sample1_unittest_LDADD = lib/libgtest_main.la \
lib/libgtest.la \
samples/libsamples.la
# Another sample. It also verifies that libgtest works.
TESTS += samples/sample10_unittest
check_PROGRAMS += samples/sample10_unittest
samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
samples_sample10_unittest_LDADD = lib/libgtest.la
# This tests most constructs of gtest and verifies that libgtest_main
# and libgtest work.
TESTS += test/gtest_all_test
check_PROGRAMS += test/gtest_all_test
test_gtest_all_test_SOURCES = test/gtest_all_test.cc
test_gtest_all_test_LDADD = lib/libgtest_main.la \
lib/libgtest.la
# Tests that fused gtest files compile and work.
FUSED_GTEST_SRC = \
fused-src/gtest/gtest-all.cc \
fused-src/gtest/gtest.h \
fused-src/gtest/gtest_main.cc
if HAVE_PYTHON
TESTS += test/fused_gtest_test
check_PROGRAMS += test/fused_gtest_test
test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \
samples/sample1.cc samples/sample1_unittest.cc
test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src"
# Build rules for putting fused Google Test files into the distribution
# package. The user can also create those files by manually running
# scripts/fuse_gtest_files.py.
$(test_fused_gtest_test_SOURCES): fused-gtest
fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
$(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \
scripts/fuse_gtest_files.py
mkdir -p "$(srcdir)/fused-src"
chmod -R u+w "$(srcdir)/fused-src"
rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc"
rm -f "$(srcdir)/fused-src/gtest/gtest.h"
"$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src"
cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/"
maintainer-clean-local:
rm -rf "$(srcdir)/fused-src"
endif
# Death tests may produce core dumps in the build directory. In case
# this happens, clean them to keep distcleancheck happy.
CLEANFILES = core
# Disables 'make install' as installing a compiled version of Google
# Test can lead to undefined behavior due to violation of the
# One-Definition Rule.
install-exec-local:
echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system."
false
install-data-local:
echo "'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system."
false

435
src/tests/googletest/README Normal file
View file

@ -0,0 +1,435 @@
Google C++ Testing Framework
============================
http://code.google.com/p/googletest/
Overview
--------
Google's framework for writing C++ tests on a variety of platforms
(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the
xUnit architecture. Supports automatic test discovery, a rich set of
assertions, user-defined assertions, death tests, fatal and non-fatal
failures, various options for running the tests, and XML test report
generation.
Please see the project page above for more information as well as the
mailing list for questions, discussions, and development. There is
also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please
join us!
Requirements for End Users
--------------------------
Google Test is designed to have fairly minimal requirements to build
and use with your projects, but there are some. Currently, we support
Linux, Windows, Mac OS X, and Cygwin. We will also make our best
effort to support other platforms (e.g. Solaris, AIX, and z/OS).
However, since core members of the Google Test project have no access
to these platforms, Google Test may have outstanding issues there. If
you notice any problems on your platform, please notify
googletestframework@googlegroups.com. Patches for fixing them are
even more welcome!
### Linux Requirements ###
These are the base requirements to build and use Google Test from a source
package (as described below):
* GNU-compatible Make or gmake
* POSIX-standard shell
* POSIX(-2) Regular Expressions (regex.h)
* A C++98-standard-compliant compiler
### Windows Requirements ###
* Microsoft Visual C++ 7.1 or newer
### Cygwin Requirements ###
* Cygwin 1.5.25-14 or newer
### Mac OS X Requirements ###
* Mac OS X 10.4 Tiger or newer
* Developer Tools Installed
Also, you'll need CMake 2.6.4 or higher if you want to build the
samples using the provided CMake script, regardless of the platform.
Requirements for Contributors
-----------------------------
We welcome patches. If you plan to contribute a patch, you need to
build Google Test and its own tests from an SVN checkout (described
below), which has further requirements:
* Python version 2.3 or newer (for running some of the tests and
re-generating certain source files from templates)
* CMake 2.6.4 or newer
Getting the Source
------------------
There are two primary ways of getting Google Test's source code: you
can download a stable source release in your preferred archive format,
or directly check out the source from our Subversion (SVN) repositary.
The SVN checkout requires a few extra steps and some extra software
packages on your system, but lets you track the latest development and
make patches much more easily, so we highly encourage it.
### Source Package ###
Google Test is released in versioned source packages which can be
downloaded from the download page [1]. Several different archive
formats are provided, but the only difference is the tools used to
manipulate them, and the size of the resulting file. Download
whichever you are most comfortable with.
[1] http://code.google.com/p/googletest/downloads/list
Once the package is downloaded, expand it using whichever tools you
prefer for that type. This will result in a new directory with the
name "gtest-X.Y.Z" which contains all of the source code. Here are
some examples on Linux:
tar -xvzf gtest-X.Y.Z.tar.gz
tar -xvjf gtest-X.Y.Z.tar.bz2
unzip gtest-X.Y.Z.zip
### SVN Checkout ###
To check out the main branch (also known as the "trunk") of Google
Test, run the following Subversion command:
svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
Setting up the Build
--------------------
To build Google Test and your tests that use it, you need to tell your
build system where to find its headers and source files. The exact
way to do it depends on which build system you use, and is usually
straightforward.
### Generic Build Instructions ###
Suppose you put Google Test in directory ${GTEST_DIR}. To build it,
create a library build target (or a project as called by Visual Studio
and Xcode) to compile
${GTEST_DIR}/src/gtest-all.cc
with ${GTEST_DIR}/include in the system header search path and ${GTEST_DIR}
in the normal header search path. Assuming a Linux-like system and gcc,
something like the following will do:
g++ -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \
-pthread -c ${GTEST_DIR}/src/gtest-all.cc
ar -rv libgtest.a gtest-all.o
(We need -pthread as Google Test uses threads.)
Next, you should compile your test source file with
${GTEST_DIR}/include in the system header search path, and link it
with gtest and any other necessary libraries:
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
-o your_test
As an example, the make/ directory contains a Makefile that you can
use to build Google Test on systems where GNU make is available
(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google
Test's own tests. Instead, it just builds the Google Test library and
a sample test. You can use it as a starting point for your own build
script.
If the default settings are correct for your environment, the
following commands should succeed:
cd ${GTEST_DIR}/make
make
./sample1_unittest
If you see errors, try to tweak the contents of make/Makefile to make
them go away. There are instructions in make/Makefile on how to do
it.
### Using CMake ###
Google Test comes with a CMake build script (CMakeLists.txt) that can
be used on a wide range of platforms ("C" stands for cross-platofrm.).
If you don't have CMake installed already, you can download it for
free from http://www.cmake.org/.
CMake works by generating native makefiles or build projects that can
be used in the compiler environment of your choice. The typical
workflow starts with:
mkdir mybuild # Create a directory to hold the build output.
cd mybuild
cmake ${GTEST_DIR} # Generate native build scripts.
If you want to build Google Test's samples, you should replace the
last command with
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
If you are on a *nix system, you should now see a Makefile in the
current directory. Just type 'make' to build gtest.
If you use Windows and have Vistual Studio installed, a gtest.sln file
and several .vcproj files will be created. You can then build them
using Visual Studio.
On Mac OS X with Xcode installed, a .xcodeproj file will be generated.
### Legacy Build Scripts ###
Before settling on CMake, we have been providing hand-maintained build
projects/scripts for Visual Studio, Xcode, and Autotools. While we
continue to provide them for convenience, they are not actively
maintained any more. We highly recommend that you follow the
instructions in the previous two sections to integrate Google Test
with your existing build system.
If you still need to use the legacy build scripts, here's how:
The msvc\ folder contains two solutions with Visual C++ projects.
Open the gtest.sln or gtest-md.sln file using Visual Studio, and you
are ready to build Google Test the same way you build any Visual
Studio project. Files that have names ending with -md use DLL
versions of Microsoft runtime libraries (the /MD or the /MDd compiler
option). Files without that suffix use static versions of the runtime
libraries (the /MT or the /MTd option). Please note that one must use
the same option to compile both gtest and the test code. If you use
Visual Studio 2005 or above, we recommend the -md version as /MD is
the default for new projects in these versions of Visual Studio.
On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using
Xcode. Build the "gtest" target. The universal binary framework will
end up in your selected build directory (selected in the Xcode
"Preferences..." -> "Building" pane and defaults to xcode/build).
Alternatively, at the command line, enter:
xcodebuild
This will build the "Release" configuration of gtest.framework in your
default build location. See the "xcodebuild" man page for more
information about building different configurations and building in
different locations.
If you wish to use the Google Test Xcode project with Xcode 4.x and
above, you need to either:
* update the SDK configuration options in xcode/Config/General.xconfig.
Comment options SDKROOT, MACOS_DEPLOYMENT_TARGET, and GCC_VERSION. If
you choose this route you lose the ability to target earlier versions
of MacOS X.
* Install an SDK for an earlier version. This doesn't appear to be
supported by Apple, but has been reported to work
(http://stackoverflow.com/questions/5378518).
Tweaking Google Test
--------------------
Google Test can be used in diverse environments. The default
configuration may not work (or may not work well) out of the box in
some environments. However, you can easily tweak Google Test by
defining control macros on the compiler command line. Generally,
these macros are named like GTEST_XYZ and you define them to either 1
or 0 to enable or disable a certain feature.
We list the most frequently used macros below. For a complete list,
see file include/gtest/internal/gtest-port.h.
### Choosing a TR1 Tuple Library ###
Some Google Test features require the C++ Technical Report 1 (TR1)
tuple library, which is not yet available with all compilers. The
good news is that Google Test implements a subset of TR1 tuple that's
enough for its own need, and will automatically use this when the
compiler doesn't provide TR1 tuple.
Usually you don't need to care about which tuple library Google Test
uses. However, if your project already uses TR1 tuple, you need to
tell Google Test to use the same TR1 tuple library the rest of your
project uses, or the two tuple implementations will clash. To do
that, add
-DGTEST_USE_OWN_TR1_TUPLE=0
to the compiler flags while compiling Google Test and your tests. If
you want to force Google Test to use its own tuple library, just add
-DGTEST_USE_OWN_TR1_TUPLE=1
to the compiler flags instead.
If you don't want Google Test to use tuple at all, add
-DGTEST_HAS_TR1_TUPLE=0
and all features using tuple will be disabled.
### Multi-threaded Tests ###
Google Test is thread-safe where the pthread library is available.
After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE
macro to see whether this is the case (yes if the macro is #defined to
1, no if it's undefined.).
If Google Test doesn't correctly detect whether pthread is available
in your environment, you can force it with
-DGTEST_HAS_PTHREAD=1
or
-DGTEST_HAS_PTHREAD=0
When Google Test uses pthread, you may need to add flags to your
compiler and/or linker to select the pthread library, or you'll get
link errors. If you use the CMake script or the deprecated Autotools
script, this is taken care of for you. If you use your own build
script, you'll need to read your compiler and linker's manual to
figure out what flags to add.
### As a Shared Library (DLL) ###
Google Test is compact, so most users can build and link it as a
static library for the simplicity. You can choose to use Google Test
as a shared library (known as a DLL on Windows) if you prefer.
To compile *gtest* as a shared library, add
-DGTEST_CREATE_SHARED_LIBRARY=1
to the compiler flags. You'll also need to tell the linker to produce
a shared library instead - consult your linker's manual for how to do
it.
To compile your *tests* that use the gtest shared library, add
-DGTEST_LINKED_AS_SHARED_LIBRARY=1
to the compiler flags.
Note: while the above steps aren't technically necessary today when
using some compilers (e.g. GCC), they may become necessary in the
future, if we decide to improve the speed of loading the library (see
http://gcc.gnu.org/wiki/Visibility for details). Therefore you are
recommended to always add the above flags when using Google Test as a
shared library. Otherwise a future release of Google Test may break
your build script.
### Avoiding Macro Name Clashes ###
In C++, macros don't obey namespaces. Therefore two libraries that
both define a macro of the same name will clash if you #include both
definitions. In case a Google Test macro clashes with another
library, you can force Google Test to rename its macro to avoid the
conflict.
Specifically, if both Google Test and some other code define macro
FOO, you can add
-DGTEST_DONT_DEFINE_FOO=1
to the compiler flags to tell Google Test to change the macro's name
from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST.
For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write
GTEST_TEST(SomeTest, DoesThis) { ... }
instead of
TEST(SomeTest, DoesThis) { ... }
in order to define a test.
Upgrating from an Earlier Version
---------------------------------
We strive to keep Google Test releases backward compatible.
Sometimes, though, we have to make some breaking changes for the
users' long-term benefits. This section describes what you'll need to
do if you are upgrading from an earlier version of Google Test.
### Upgrading from 1.3.0 or Earlier ###
You may need to explicitly enable or disable Google Test's own TR1
tuple library. See the instructions in section "Choosing a TR1 Tuple
Library".
### Upgrading from 1.4.0 or Earlier ###
The Autotools build script (configure + make) is no longer officially
supportted. You are encouraged to migrate to your own build system or
use CMake. If you still need to use Autotools, you can find
instructions in the README file from Google Test 1.4.0.
On platforms where the pthread library is available, Google Test uses
it in order to be thread-safe. See the "Multi-threaded Tests" section
for what this means to your build script.
If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google
Test will no longer compile. This should affect very few people, as a
large portion of STL (including <string>) doesn't compile in this mode
anyway. We decided to stop supporting it in order to greatly simplify
Google Test's implementation.
Developing Google Test
----------------------
This section discusses how to make your own changes to Google Test.
### Testing Google Test Itself ###
To make sure your changes work as intended and don't break existing
functionality, you'll want to compile and run Google Test's own tests.
For that you can use CMake:
mkdir mybuild
cd mybuild
cmake -Dgtest_build_tests=ON ${GTEST_DIR}
Make sure you have Python installed, as some of Google Test's tests
are written in Python. If the cmake command complains about not being
able to find Python ("Could NOT find PythonInterp (missing:
PYTHON_EXECUTABLE)"), try telling it explicitly where your Python
executable can be found:
cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR}
Next, you can build Google Test and all of its own tests. On *nix,
this is usually done by 'make'. To run the tests, do
make test
All tests should pass.
### Regenerating Source Files ###
Some of Google Test's source files are generated from templates (not
in the C++ sense) using a script. A template file is named FOO.pump,
where FOO is the name of the file it will generate. For example, the
file include/gtest/internal/gtest-type-util.h.pump is used to generate
gtest-type-util.h in the same directory.
Normally you don't need to worry about regenerating the source files,
unless you need to modify them. In that case, you should modify the
corresponding .pump files instead and run the pump.py Python script to
regenerate them. You can find pump.py in the scripts/ directory.
Read the Pump manual [2] for how to use it.
[2] http://code.google.com/p/googletest/wiki/PumpManual
### Contributing a Patch ###
We welcome patches. Please read the Google Test developer's guide [3]
for how you can contribute. In particular, make sure you have signed
the Contributor License Agreement, or we won't be able to accept the
patch.
[3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide
Happy testing!

View file

View file

@ -0,0 +1,227 @@
# Defines functions and macros useful for building Google Test and
# Google Mock.
#
# Note:
#
# - This file will be run twice when building Google Mock (once via
# Google Test's CMakeLists.txt, and once via Google Mock's).
# Therefore it shouldn't have any side effects other than defining
# the functions and macros.
#
# - The functions/macros defined in this file may depend on Google
# Test and Google Mock's option() definitions, and thus must be
# called *after* the options have been defined.
# Tweaks CMake's default compiler/linker settings to suit Google Test's needs.
#
# This must be a macro(), as inside a function string() can only
# update variables in the function scope.
macro(fix_default_compiler_settings_)
if (MSVC)
# For MSVC, CMake sets certain flags to defaults we want to override.
# This replacement code is taken from sample in the CMake Wiki at
# http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace.
foreach (flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if (NOT BUILD_SHARED_LIBS AND NOT gtest_force_shared_crt)
# When Google Test is built as a shared library, it should also use
# shared runtime libraries. Otherwise, it may end up with multiple
# copies of runtime library data in different modules, resulting in
# hard-to-find crashes. When it is built as a static library, it is
# preferable to use CRT as static libraries, as we don't have to rely
# on CRT DLLs being available. CMake always defaults to using shared
# CRT libraries, so we override that default here.
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
endif()
# We prefer more strict warning checking for building Google Test.
# Replaces /W3 with /W4 in defaults.
string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}")
endforeach()
endif()
endmacro()
# Defines the compiler/linker flags used to build Google Test and
# Google Mock. You can tweak these definitions to suit your need. A
# variable's value is empty before it's explicitly assigned to.
macro(config_compiler_and_linker)
if (NOT gtest_disable_pthreads)
# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
find_package(Threads)
endif()
fix_default_compiler_settings_()
if (MSVC)
# Newlines inside flags variables break CMake's NMake generator.
# TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds.
set(cxx_base_flags "-GS -W4 -WX -wd4127 -wd4251 -wd4275 -nologo -J -Zi")
if (MSVC_VERSION LESS 1400)
# Suppress spurious warnings MSVC 7.1 sometimes issues.
# Forcing value to bool.
set(cxx_base_flags "${cxx_base_flags} -wd4800")
# Copy constructor and assignment operator could not be generated.
set(cxx_base_flags "${cxx_base_flags} -wd4511 -wd4512")
# Compatibility warnings not applicable to Google Test.
# Resolved overload was found by argument-dependent lookup.
set(cxx_base_flags "${cxx_base_flags} -wd4675")
endif()
set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-GR-")
elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow")
set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions")
# Until version 4.3.2, GCC doesn't define a macro to indicate
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly.
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(cxx_exception_flags "-features=except")
# Sun Pro doesn't provide macros to indicate whether exceptions and
# RTTI are enabled, so we define GTEST_HAS_* explicitly.
set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
CMAKE_CXX_COMPILER_ID STREQUAL "XL")
# CMake 2.8 changes Visual Age's compiler ID to "XL".
set(cxx_exception_flags "-qeh")
set(cxx_no_exception_flags "-qnoeh")
# Until version 9.0, Visual Age doesn't define a macro to indicate
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly.
set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP")
set(cxx_base_flags "-AA -mt")
set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1")
set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0")
# RTTI can not be disabled in HP aCC compiler.
set(cxx_no_rtti_flags "")
endif()
if (CMAKE_USE_PTHREADS_INIT) # The pthreads library is available and allowed.
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1")
else()
set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=0")
endif()
# For building gtest's own tests and samples.
set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}")
set(cxx_no_exception
"${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
set(cxx_default "${cxx_exception}")
set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1")
# For building the gtest libraries.
set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
endmacro()
# Defines the gtest & gtest_main libraries. User tests should link
# with one of them.
function(cxx_library_with_type name type cxx_flags)
# type can be either STATIC or SHARED to denote a static or shared library.
# ARGN refers to additional arguments after 'cxx_flags'.
add_library(${name} ${type} ${ARGN})
set_target_properties(${name}
PROPERTIES
COMPILE_FLAGS "${cxx_flags}")
if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED")
set_target_properties(${name}
PROPERTIES
COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1")
endif()
if (CMAKE_USE_PTHREADS_INIT)
target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
endif()
endfunction()
########################################################################
#
# Helper functions for creating build targets.
function(cxx_shared_library name cxx_flags)
cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN})
endfunction()
function(cxx_library name cxx_flags)
cxx_library_with_type(${name} "" "${cxx_flags}" ${ARGN})
endfunction()
# cxx_executable_with_flags(name cxx_flags libs srcs...)
#
# creates a named C++ executable that depends on the given libraries and
# is built from the given source files with the given compiler flags.
function(cxx_executable_with_flags name cxx_flags libs)
add_executable(${name} ${ARGN})
if (cxx_flags)
set_target_properties(${name}
PROPERTIES
COMPILE_FLAGS "${cxx_flags}")
endif()
if (BUILD_SHARED_LIBS)
set_target_properties(${name}
PROPERTIES
COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
endif()
# To support mixing linking in static and dynamic libraries, link each
# library in with an extra call to target_link_libraries.
foreach (lib "${libs}")
target_link_libraries(${name} ${lib})
endforeach()
endfunction()
# cxx_executable(name dir lib srcs...)
#
# creates a named target that depends on the given libs and is built
# from the given source files. dir/name.cc is implicitly included in
# the source file list.
function(cxx_executable name dir libs)
cxx_executable_with_flags(
${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN})
endfunction()
# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE.
find_package(PythonInterp)
# cxx_test_with_flags(name cxx_flags libs srcs...)
#
# creates a named C++ test that depends on the given libs and is built
# from the given source files with the given compiler flags.
function(cxx_test_with_flags name cxx_flags libs)
cxx_executable_with_flags(${name} "${cxx_flags}" "${libs}" ${ARGN})
add_test(${name} ${name})
endfunction()
# cxx_test(name libs srcs...)
#
# creates a named test target that depends on the given libs and is
# built from the given source files. Unlike cxx_test_with_flags,
# test/name.cc is already implicitly included in the source file list.
function(cxx_test name libs)
cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
"test/${name}.cc" ${ARGN})
endfunction()
# py_test(name)
#
# creates a Python test with the given name whose main module is in
# test/name.py. It does nothing if Python is not installed.
function(py_test name)
# We are not supporting Python tests on Linux yet as they consider
# all Linux environments to be google3 and try to use google3 features.
if (PYTHONINTERP_FOUND)
# ${CMAKE_BINARY_DIR} is known at configuration time, so we can
# directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known
# only at ctest runtime (by calling ctest -c <Configuration>), so
# we have to escape $ to delay variable substitution here.
add_test(${name}
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py
--build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE})
endif()
endfunction()

View file

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{bca37a72-5b07-46cf-b44e-89f8e06451a2}</ProjectGuid>
<Config Condition="'$(Config)'==''">Release</Config>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Base>true</Base>
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Base>true</Base>
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<OutputExt>lib</OutputExt>
<DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>
<Defines>NO_STRICT</Defines>
<DynamicRTL>true</DynamicRTL>
<UsePackages>true</UsePackages>
<ProjectType>CppStaticLibrary</ProjectType>
<BCC_CPPCompileAlways>true</BCC_CPPCompileAlways>
<PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi</PackageImports>
<BCC_wpar>false</BCC_wpar>
<IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</IncludePath>
<AllPackageLibs>rtl.lib;vcl.lib</AllPackageLibs>
<TLIB_PageSize>32</TLIB_PageSize>
<ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</ILINK_LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>
<DCC_Optimize>false</DCC_Optimize>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<Defines>_DEBUG;$(Defines)</Defines>
<ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>
<BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>
<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
<BCC_UseRegisterVariables>None</BCC_UseRegisterVariables>
<DCC_Define>DEBUG</DCC_Define>
<BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>
<IntermediateOutputDir>Debug</IntermediateOutputDir>
<TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>
<BCC_StackFrames>true</BCC_StackFrames>
<BCC_DisableOptimizations>true</BCC_DisableOptimizations>
<ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>Full</TASM_Debugging>
<BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<Defines>NDEBUG;$(Defines)</Defines>
<IntermediateOutputDir>Release</IntermediateOutputDir>
<ILINK_LibraryPath>$(BDS)\lib\release;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>None</TASM_Debugging>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>CPlusPlusBuilder.Personality</Borland.Personality>
<Borland.ProjectType>CppStaticLibrary</Borland.ProjectType>
<BorlandProject>
<BorlandProject><CPlusPlusBuilder.Personality><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1033</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Debugging><Debugging Name="DebugSourceDirs"></Debugging></Debugging><Parameters><Parameters Name="RunParams"></Parameters><Parameters Name="Launcher"></Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="DebugCWD"></Parameters><Parameters Name="HostApplication"></Parameters><Parameters Name="RemoteHost"></Parameters><Parameters Name="RemotePath"></Parameters><Parameters Name="RemoteParams"></Parameters><Parameters Name="RemoteLauncher"></Parameters><Parameters Name="UseRemoteLauncher">False</Parameters><Parameters Name="RemoteCWD"></Parameters><Parameters Name="RemoteDebug">False</Parameters><Parameters Name="Debug Symbols Search Path"></Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\bcboffice2k100.bpl">CodeGear C++Builder Office 2000 Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\bcbofficexp100.bpl">CodeGear C++Builder Office XP Servers Package</Excluded_Packages>
</Excluded_Packages><Linker><Linker Name="LibPrefix"></Linker><Linker Name="LibSuffix"></Linker><Linker Name="LibVersion"></Linker></Linker><ProjectProperties><ProjectProperties Name="AutoShowDeps">False</ProjectProperties><ProjectProperties Name="ManagePaths">True</ProjectProperties><ProjectProperties Name="VerifyPackages">True</ProjectProperties></ProjectProperties><HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Count">3</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item0">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item1">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item2">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include</HistoryLists_hlIncludePath></HistoryLists_hlIncludePath><HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Count">1</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item0">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</HistoryLists_hlILINK_LibraryPath></HistoryLists_hlILINK_LibraryPath><HistoryLists_hlDefines><HistoryLists_hlDefines Name="Count">1</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item0">NO_STRICT</HistoryLists_hlDefines></HistoryLists_hlDefines><HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Count">1</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item0">32</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item1">16</HistoryLists_hlTLIB_PageSize></HistoryLists_hlTLIB_PageSize></CPlusPlusBuilder.Personality></BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Cpp.Targets" />
<ItemGroup>
<None Include="..\include\gtest\gtest-death-test.h">
<BuildOrder>3</BuildOrder>
</None>
<None Include="..\include\gtest\gtest-message.h">
<BuildOrder>4</BuildOrder>
</None>
<None Include="..\include\gtest\gtest-param-test.h">
<BuildOrder>5</BuildOrder>
</None>
<None Include="..\include\gtest\gtest-spi.h">
<BuildOrder>6</BuildOrder>
</None>
<None Include="..\include\gtest\gtest-test-part.h">
<BuildOrder>7</BuildOrder>
</None>
<None Include="..\include\gtest\gtest-typed-test.h">
<BuildOrder>8</BuildOrder>
</None>
<None Include="..\include\gtest\gtest.h">
<BuildOrder>0</BuildOrder>
</None>
<None Include="..\include\gtest\gtest_pred_impl.h">
<BuildOrder>1</BuildOrder>
</None>
<None Include="..\include\gtest\gtest_prod.h">
<BuildOrder>2</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-death-test-internal.h">
<BuildOrder>9</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-filepath.h">
<BuildOrder>10</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-internal.h">
<BuildOrder>11</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-linked_ptr.h">
<BuildOrder>12</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-param-util-generated.h">
<BuildOrder>14</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-param-util.h">
<BuildOrder>13</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-port.h">
<BuildOrder>15</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-string.h">
<BuildOrder>16</BuildOrder>
</None>
<None Include="..\include\gtest\internal\gtest-type-util.h">
<BuildOrder>17</BuildOrder>
</None>
<CppCompile Include="gtest_all.cc">
<BuildOrder>18</BuildOrder>
</CppCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
</BuildConfiguration>
</ItemGroup>
</Project>

View file

@ -0,0 +1,54 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{c1d923e0-6cba-4332-9b6f-3420acbf5091}</ProjectGuid>
</PropertyGroup>
<ItemGroup />
<ItemGroup>
<Projects Include="gtest.cbproj" />
<Projects Include="gtest_main.cbproj" />
<Projects Include="gtest_unittest.cbproj" />
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Default.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject xmlns=""><Default.Personality></Default.Personality></BorlandProject></BorlandProject>
</ProjectExtensions>
<Target Name="gtest">
<MSBuild Projects="gtest.cbproj" Targets="" />
</Target>
<Target Name="gtest:Clean">
<MSBuild Projects="gtest.cbproj" Targets="Clean" />
</Target>
<Target Name="gtest:Make">
<MSBuild Projects="gtest.cbproj" Targets="Make" />
</Target>
<Target Name="gtest_main">
<MSBuild Projects="gtest_main.cbproj" Targets="" />
</Target>
<Target Name="gtest_main:Clean">
<MSBuild Projects="gtest_main.cbproj" Targets="Clean" />
</Target>
<Target Name="gtest_main:Make">
<MSBuild Projects="gtest_main.cbproj" Targets="Make" />
</Target>
<Target Name="gtest_unittest">
<MSBuild Projects="gtest_unittest.cbproj" Targets="" />
</Target>
<Target Name="gtest_unittest:Clean">
<MSBuild Projects="gtest_unittest.cbproj" Targets="Clean" />
</Target>
<Target Name="gtest_unittest:Make">
<MSBuild Projects="gtest_unittest.cbproj" Targets="Make" />
</Target>
<Target Name="Build">
<CallTarget Targets="gtest;gtest_main;gtest_unittest" />
</Target>
<Target Name="Clean">
<CallTarget Targets="gtest:Clean;gtest_main:Clean;gtest_unittest:Clean" />
</Target>
<Target Name="Make">
<CallTarget Targets="gtest:Make;gtest_main:Make;gtest_unittest:Make" />
</Target>
<Import Condition="Exists('$(MSBuildBinPath)\Borland.Group.Targets')" Project="$(MSBuildBinPath)\Borland.Group.Targets" />
</Project>

View file

@ -0,0 +1,38 @@
// Copyright 2009, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: Josh Kelley (joshkel@gmail.com)
//
// Google C++ Testing Framework (Google Test)
//
// C++Builder's IDE cannot build a static library from files with hyphens
// in their name. See http://qc.codegear.com/wc/qcmain.aspx?d=70977 .
// This file serves as a workaround.
#include "src/gtest-all.cc"

View file

@ -0,0 +1,40 @@
// Copyright 2009, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: Josh Kelley (joshkel@gmail.com)
//
// Google C++ Testing Framework (Google Test)
//
// Links gtest.lib and gtest_main.lib into the current project in C++Builder.
// This means that these libraries can't be renamed, but it's the only way to
// ensure that Debug versus Release test builds are linked against the
// appropriate Debug or Release build of the libraries.
#pragma link "gtest.lib"
#pragma link "gtest_main.lib"

View file

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{bca37a72-5b07-46cf-b44e-89f8e06451a2}</ProjectGuid>
<Config Condition="'$(Config)'==''">Release</Config>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Base>true</Base>
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Base>true</Base>
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<OutputExt>lib</OutputExt>
<DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>
<Defines>NO_STRICT</Defines>
<DynamicRTL>true</DynamicRTL>
<UsePackages>true</UsePackages>
<ProjectType>CppStaticLibrary</ProjectType>
<BCC_CPPCompileAlways>true</BCC_CPPCompileAlways>
<PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi</PackageImports>
<BCC_wpar>false</BCC_wpar>
<IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</IncludePath>
<AllPackageLibs>rtl.lib;vcl.lib</AllPackageLibs>
<TLIB_PageSize>32</TLIB_PageSize>
<ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</ILINK_LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>
<DCC_Optimize>false</DCC_Optimize>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<Defines>_DEBUG;$(Defines)</Defines>
<ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>
<BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>
<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
<BCC_UseRegisterVariables>None</BCC_UseRegisterVariables>
<DCC_Define>DEBUG</DCC_Define>
<BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>
<IntermediateOutputDir>Debug</IntermediateOutputDir>
<TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>
<BCC_StackFrames>true</BCC_StackFrames>
<BCC_DisableOptimizations>true</BCC_DisableOptimizations>
<ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>Full</TASM_Debugging>
<BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<Defines>NDEBUG;$(Defines)</Defines>
<IntermediateOutputDir>Release</IntermediateOutputDir>
<ILINK_LibraryPath>$(BDS)\lib\release;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>None</TASM_Debugging>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>CPlusPlusBuilder.Personality</Borland.Personality>
<Borland.ProjectType>CppStaticLibrary</Borland.ProjectType>
<BorlandProject>
<BorlandProject><CPlusPlusBuilder.Personality><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1033</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Debugging><Debugging Name="DebugSourceDirs"></Debugging></Debugging><Parameters><Parameters Name="RunParams"></Parameters><Parameters Name="Launcher"></Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="DebugCWD"></Parameters><Parameters Name="HostApplication"></Parameters><Parameters Name="RemoteHost"></Parameters><Parameters Name="RemotePath"></Parameters><Parameters Name="RemoteParams"></Parameters><Parameters Name="RemoteLauncher"></Parameters><Parameters Name="UseRemoteLauncher">False</Parameters><Parameters Name="RemoteCWD"></Parameters><Parameters Name="RemoteDebug">False</Parameters><Parameters Name="Debug Symbols Search Path"></Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\bcboffice2k100.bpl">CodeGear C++Builder Office 2000 Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\bcbofficexp100.bpl">CodeGear C++Builder Office XP Servers Package</Excluded_Packages>
</Excluded_Packages><Linker><Linker Name="LibPrefix"></Linker><Linker Name="LibSuffix"></Linker><Linker Name="LibVersion"></Linker></Linker><ProjectProperties><ProjectProperties Name="AutoShowDeps">False</ProjectProperties><ProjectProperties Name="ManagePaths">True</ProjectProperties><ProjectProperties Name="VerifyPackages">True</ProjectProperties></ProjectProperties><HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Count">3</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item0">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item1">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item2">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include</HistoryLists_hlIncludePath></HistoryLists_hlIncludePath><HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Count">1</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item0">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</HistoryLists_hlILINK_LibraryPath></HistoryLists_hlILINK_LibraryPath><HistoryLists_hlDefines><HistoryLists_hlDefines Name="Count">1</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item0">NO_STRICT</HistoryLists_hlDefines></HistoryLists_hlDefines><HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Count">1</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item0">32</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item1">16</HistoryLists_hlTLIB_PageSize></HistoryLists_hlTLIB_PageSize></CPlusPlusBuilder.Personality></BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Cpp.Targets" />
<ItemGroup>
<CppCompile Include="..\src\gtest_main.cc">
<BuildOrder>0</BuildOrder>
</CppCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
</BuildConfiguration>
</ItemGroup>
</Project>

View file

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{eea63393-5ac5-4b9c-8909-d75fef2daa41}</ProjectGuid>
<Config Condition="'$(Config)'==''">Release</Config>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
<Base>true</Base>
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
<Base>true</Base>
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<OutputExt>exe</OutputExt>
<BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
<Defines>NO_STRICT</Defines>
<DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>
<DynamicRTL>true</DynamicRTL>
<ILINK_ObjectSearchPath>..\test</ILINK_ObjectSearchPath>
<UsePackages>true</UsePackages>
<ProjectType>CppConsoleApplication</ProjectType>
<NoVCL>true</NoVCL>
<BCC_CPPCompileAlways>true</BCC_CPPCompileAlways>
<PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi</PackageImports>
<BCC_wpar>false</BCC_wpar>
<IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..</IncludePath>
<ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test</ILINK_LibraryPath>
<Multithreaded>true</Multithreaded>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>
<DCC_Optimize>false</DCC_Optimize>
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
<Defines>_DEBUG;$(Defines)</Defines>
<ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>
<BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>
<ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>
<BCC_UseRegisterVariables>None</BCC_UseRegisterVariables>
<DCC_Define>DEBUG</DCC_Define>
<BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>
<IntermediateOutputDir>Debug</IntermediateOutputDir>
<TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>
<BCC_StackFrames>true</BCC_StackFrames>
<BCC_DisableOptimizations>true</BCC_DisableOptimizations>
<ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>Full</TASM_Debugging>
<BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<Defines>NDEBUG;$(Defines)</Defines>
<IntermediateOutputDir>Release</IntermediateOutputDir>
<ILINK_LibraryPath>$(BDS)\lib\release;$(ILINK_LibraryPath)</ILINK_LibraryPath>
<TASM_Debugging>None</TASM_Debugging>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>CPlusPlusBuilder.Personality</Borland.Personality>
<Borland.ProjectType>CppConsoleApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject><CPlusPlusBuilder.Personality><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1033</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Debugging><Debugging Name="DebugSourceDirs"></Debugging></Debugging><Parameters><Parameters Name="RunParams"></Parameters><Parameters Name="Launcher"></Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="DebugCWD"></Parameters><Parameters Name="HostApplication"></Parameters><Parameters Name="RemoteHost"></Parameters><Parameters Name="RemotePath"></Parameters><Parameters Name="RemoteParams"></Parameters><Parameters Name="RemoteLauncher"></Parameters><Parameters Name="UseRemoteLauncher">False</Parameters><Parameters Name="RemoteCWD"></Parameters><Parameters Name="RemoteDebug">False</Parameters><Parameters Name="Debug Symbols Search Path"></Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\bcboffice2k100.bpl">CodeGear C++Builder Office 2000 Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDS)\bin\bcbofficexp100.bpl">CodeGear C++Builder Office XP Servers Package</Excluded_Packages>
</Excluded_Packages><Linker><Linker Name="LibPrefix"></Linker><Linker Name="LibSuffix"></Linker><Linker Name="LibVersion"></Linker></Linker><ProjectProperties><ProjectProperties Name="AutoShowDeps">False</ProjectProperties><ProjectProperties Name="ManagePaths">True</ProjectProperties><ProjectProperties Name="VerifyPackages">True</ProjectProperties></ProjectProperties><HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Count">3</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item0">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item1">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item2">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include</HistoryLists_hlIncludePath></HistoryLists_hlIncludePath><HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Count">1</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item0">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item1">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item2">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test</HistoryLists_hlILINK_LibraryPath></HistoryLists_hlILINK_LibraryPath><HistoryLists_hlDefines><HistoryLists_hlDefines Name="Count">2</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item0">NO_STRICT</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item1">STRICT</HistoryLists_hlDefines></HistoryLists_hlDefines></CPlusPlusBuilder.Personality></BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Cpp.Targets" />
<ItemGroup>
<CppCompile Include="..\test\gtest_unittest.cc">
<BuildOrder>0</BuildOrder>
</CppCompile>
<CppCompile Include="gtest_link.cc">
<BuildOrder>1</BuildOrder>
</CppCompile>
<BuildConfiguration Include="Debug">
<Key>Cfg_1</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_2</Key>
</BuildConfiguration>
</ItemGroup>
</Project>

View file

@ -0,0 +1,68 @@
m4_include(m4/acx_pthread.m4)
# At this point, the Xcode project assumes the version string will be three
# integers separated by periods and surrounded by square brackets (e.g.
# "[1.0.1]"). It also asumes that there won't be any closing parenthesis
# between "AC_INIT(" and the closing ")" including comments and strings.
AC_INIT([Google C++ Testing Framework],
[1.7.0],
[googletestframework@googlegroups.com],
[gtest])
# Provide various options to initialize the Autoconf and configure processes.
AC_PREREQ([2.59])
AC_CONFIG_SRCDIR([./LICENSE])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([build-aux/config.h])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([scripts/gtest-config], [chmod +x scripts/gtest-config])
# Initialize Automake with various options. We require at least v1.9, prevent
# pedantic complaints about package files, and enable various distribution
# targets.
AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects])
# Check for programs used in building Google Test.
AC_PROG_CC
AC_PROG_CXX
AC_LANG([C++])
AC_PROG_LIBTOOL
# TODO(chandlerc@google.com): Currently we aren't running the Python tests
# against the interpreter detected by AM_PATH_PYTHON, and so we condition
# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's
# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env"
# hashbang.
PYTHON= # We *do not* allow the user to specify a python interpreter
AC_PATH_PROG([PYTHON],[python],[:])
AS_IF([test "$PYTHON" != ":"],
[AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])])
AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"])
# Configure pthreads.
AC_ARG_WITH([pthreads],
[AS_HELP_STRING([--with-pthreads],
[use pthreads (default is yes)])],
[with_pthreads=$withval],
[with_pthreads=check])
have_pthreads=no
AS_IF([test "x$with_pthreads" != "xno"],
[ACX_PTHREAD(
[],
[AS_IF([test "x$with_pthreads" != "xcheck"],
[AC_MSG_FAILURE(
[--with-pthreads was specified, but unable to be used])])])
have_pthreads="$acx_pthread_ok"])
AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" = "xyes"])
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_LIBS)
# TODO(chandlerc@google.com) Check for the necessary system headers.
# TODO(chandlerc@google.com) Check the types, structures, and other compiler
# and architecture characteristics.
# Output the generated files. No further autoconf macros may be used.
AC_OUTPUT

View file

@ -0,0 +1,30 @@
#-------------------------------------------------
#
# Project created by QtCreator 2013-11-10T17:45:22
#
#-------------------------------------------------
QT -= core gui
TARGET = googletest
TEMPLATE = lib
DEFINES += GOOGLETEST_LIBRARY
#QMAKE_CXXFLAGS += -pthread
INCLUDEPATH += . ./include
SOURCES += \
src/gtest-all.cc
HEADERS +=
unix:!symbian {
maemo5 {
target.path = /opt/usr/lib
} else {
target.path = /usr/lib
}
INSTALLS += target
}

View file

@ -0,0 +1,294 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines the public API for death tests. It is
// #included by gtest.h so a user doesn't need to include this
// directly.
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#include "gtest/internal/gtest-death-test-internal.h"
namespace testing {
// This flag controls the style of death tests. Valid values are "threadsafe",
// meaning that the death test child process will re-execute the test binary
// from the start, running only a single death test, or "fast",
// meaning that the child process will execute the test logic immediately
// after forking.
GTEST_DECLARE_string_(death_test_style);
#if GTEST_HAS_DEATH_TEST
namespace internal {
// Returns a Boolean value indicating whether the caller is currently
// executing in the context of the death test child process. Tools such as
// Valgrind heap checkers may need this to modify their behavior in death
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
GTEST_API_ bool InDeathTestChild();
} // namespace internal
// The following macros are useful for writing death tests.
// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is
// executed:
//
// 1. It generates a warning if there is more than one active
// thread. This is because it's safe to fork() or clone() only
// when there is a single thread.
//
// 2. The parent process clone()s a sub-process and runs the death
// test in it; the sub-process exits with code 0 at the end of the
// death test, if it hasn't exited already.
//
// 3. The parent process waits for the sub-process to terminate.
//
// 4. The parent process checks the exit code and error message of
// the sub-process.
//
// Examples:
//
// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number");
// for (int i = 0; i < 5; i++) {
// EXPECT_DEATH(server.ProcessRequest(i),
// "Invalid request .* in ProcessRequest()")
// << "Failed to die on request " << i;
// }
//
// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting");
//
// bool KilledBySIGHUP(int exit_code) {
// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP;
// }
//
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
//
// On the regular expressions used in death tests:
//
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
// which uses the POSIX extended regex syntax.
//
// On other platforms (e.g. Windows), we only support a simple regex
// syntax implemented as part of Google Test. This limited
// implementation should be enough most of the time when writing
// death tests; though it lacks many features you can find in PCRE
// or POSIX extended regex syntax. For example, we don't support
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
// repetition count ("x{5,7}"), among others.
//
// Below is the syntax that we do support. We chose it to be a
// subset of both PCRE and POSIX extended regex, so it's easy to
// learn wherever you come from. In the following: 'A' denotes a
// literal character, period (.), or a single \\ escape sequence;
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
// natural numbers.
//
// c matches any literal character c
// \\d matches any decimal digit
// \\D matches any character that's not a decimal digit
// \\f matches \f
// \\n matches \n
// \\r matches \r
// \\s matches any ASCII whitespace, including \n
// \\S matches any character that's not a whitespace
// \\t matches \t
// \\v matches \v
// \\w matches any letter, _, or decimal digit
// \\W matches any character that \\w doesn't match
// \\c matches any literal character c, which must be a punctuation
// . matches any single character except \n
// A? matches 0 or 1 occurrences of A
// A* matches 0 or many occurrences of A
// A+ matches 1 or many occurrences of A
// ^ matches the beginning of a string (not that of each line)
// $ matches the end of a string (not that of each line)
// xy matches x followed by y
//
// If you accidentally use PCRE or POSIX extended regex features
// not implemented by us, you will get a run-time failure. In that
// case, please try to rewrite your regular expression within the
// above syntax.
//
// This implementation is *not* meant to be as highly tuned or robust
// as a compiled regex library, but should perform well enough for a
// death test, which already incurs significant overhead by launching
// a child process.
//
// Known caveats:
//
// A "threadsafe" style death test obtains the path to the test
// program from argv[0] and re-executes it in the sub-process. For
// simplicity, the current implementation doesn't search the PATH
// when launching the sub-process. This means that the user must
// invoke the test program via a path that contains at least one
// path separator (e.g. path/to/foo_test and
// /absolute/path/to/bar_test are fine, but foo_test is not). This
// is rarely a problem as people usually don't put the test binary
// directory in PATH.
//
// TODO(wan@google.com): make thread-safe death tests search the PATH.
// Asserts that a given statement causes the program to exit, with an
// integer exit status that satisfies predicate, and emitting error output
// that matches regex.
# define ASSERT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
// Like ASSERT_EXIT, but continues on to successive tests in the
// test case, if any:
# define EXPECT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
// Asserts that a given statement causes the program to exit, either by
// explicitly exiting with a nonzero exit code or being killed by a
// signal, and emitting error output that matches regex.
# define ASSERT_DEATH(statement, regex) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// Like ASSERT_DEATH, but continues on to successive tests in the
// test case, if any:
# define EXPECT_DEATH(statement, regex) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
// Tests that an exit code describes a normal exit with a given exit code.
class GTEST_API_ ExitedWithCode {
public:
explicit ExitedWithCode(int exit_code);
bool operator()(int exit_status) const;
private:
// No implementation - assignment is unsupported.
void operator=(const ExitedWithCode& other);
const int exit_code_;
};
# if !GTEST_OS_WINDOWS
// Tests that an exit code describes an exit due to termination by a
// given signal.
class GTEST_API_ KilledBySignal {
public:
explicit KilledBySignal(int signum);
bool operator()(int exit_status) const;
private:
const int signum_;
};
# endif // !GTEST_OS_WINDOWS
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
// The death testing framework causes this to have interesting semantics,
// since the sideeffects of the call are only visible in opt mode, and not
// in debug mode.
//
// In practice, this can be used to test functions that utilize the
// LOG(DFATAL) macro using the following style:
//
// int DieInDebugOr12(int* sideeffect) {
// if (sideeffect) {
// *sideeffect = 12;
// }
// LOG(DFATAL) << "death";
// return 12;
// }
//
// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
// int sideeffect = 0;
// // Only asserts in dbg.
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
//
// #ifdef NDEBUG
// // opt-mode has sideeffect visible.
// EXPECT_EQ(12, sideeffect);
// #else
// // dbg-mode no visible sideeffect.
// EXPECT_EQ(0, sideeffect);
// #endif
// }
//
// This will assert that DieInDebugReturn12InOpt() crashes in debug
// mode, usually due to a DCHECK or LOG(DFATAL), but returns the
// appropriate fallback value (12 in this case) in opt mode. If you
// need to test that a function has appropriate side-effects in opt
// mode, include assertions against the side-effects. A general
// pattern for this is:
//
// EXPECT_DEBUG_DEATH({
// // Side-effects here will have an effect after this statement in
// // opt mode, but none in debug mode.
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
// }, "death");
//
# ifdef NDEBUG
# define EXPECT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# else
# define EXPECT_DEBUG_DEATH(statement, regex) \
EXPECT_DEATH(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
ASSERT_DEATH(statement, regex)
# endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // GTEST_HAS_DEATH_TEST
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
// death tests are supported; otherwise they just issue a warning. This is
// useful when you are combining death test assertions with normal test
// assertions in one test.
#if GTEST_HAS_DEATH_TEST
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
EXPECT_DEATH(statement, regex)
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
ASSERT_DEATH(statement, regex)
#else
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
#endif
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_

View file

@ -0,0 +1,250 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines the Message class.
//
// IMPORTANT NOTE: Due to limitation of the C++ language, we have to
// leave some internal implementation details in this header file.
// They are clearly marked by comments like this:
//
// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
//
// Such code is NOT meant to be used by a user directly, and is subject
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
// program!
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#include <limits>
#include "gtest/internal/gtest-port.h"
// Ensures that there is at least one operator<< in the global namespace.
// See Message& operator<<(...) below for why.
void operator<<(const testing::internal::Secret&, int);
namespace testing {
// The Message class works like an ostream repeater.
//
// Typical usage:
//
// 1. You stream a bunch of values to a Message object.
// It will remember the text in a stringstream.
// 2. Then you stream the Message object to an ostream.
// This causes the text in the Message to be streamed
// to the ostream.
//
// For example;
//
// testing::Message foo;
// foo << 1 << " != " << 2;
// std::cout << foo;
//
// will print "1 != 2".
//
// Message is not intended to be inherited from. In particular, its
// destructor is not virtual.
//
// Note that stringstream behaves differently in gcc and in MSVC. You
// can stream a NULL char pointer to it in the former, but not in the
// latter (it causes an access violation if you do). The Message
// class hides this difference by treating a NULL char pointer as
// "(null)".
class GTEST_API_ Message {
private:
// The type of basic IO manipulators (endl, ends, and flush) for
// narrow streams.
typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&);
public:
// Constructs an empty Message.
Message();
// Copy constructor.
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
*ss_ << msg.GetString();
}
// Constructs a Message from a C-string.
explicit Message(const char* str) : ss_(new ::std::stringstream) {
*ss_ << str;
}
#if GTEST_OS_SYMBIAN
// Streams a value (either a pointer or not) to this object.
template <typename T>
inline Message& operator <<(const T& value) {
StreamHelper(typename internal::is_pointer<T>::type(), value);
return *this;
}
#else
// Streams a non-pointer value to this object.
template <typename T>
inline Message& operator <<(const T& val) {
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
// overloads are visible in either the std namespace or the global
// namespace, but not other namespaces, including the testing
// namespace which Google Test's Message class is in.
//
// To allow STL containers (and other types that has a << operator
// defined in the global namespace) to be used in Google Test
// assertions, testing::Message must access the custom << operator
// from the global namespace. With this using declaration,
// overloads of << defined in the global namespace and those
// visible via Koenig lookup are both exposed in this function.
using ::operator <<;
*ss_ << val;
return *this;
}
// Streams a pointer value to this object.
//
// This function is an overload of the previous one. When you
// stream a pointer to a Message, this definition will be used as it
// is more specialized. (The C++ Standard, section
// [temp.func.order].) If you stream a non-pointer, then the
// previous definition will be used.
//
// The reason for this overload is that streaming a NULL pointer to
// ostream is undefined behavior. Depending on the compiler, you
// may get "0", "(nil)", "(null)", or an access violation. To
// ensure consistent result across compilers, we always treat NULL
// as "(null)".
template <typename T>
inline Message& operator <<(T* const& pointer) { // NOLINT
if (pointer == NULL) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
return *this;
}
#endif // GTEST_OS_SYMBIAN
// Since the basic IO manipulators are overloaded for both narrow
// and wide streams, we have to provide this specialized definition
// of operator <<, even though its body is the same as the
// templatized version above. Without this definition, streaming
// endl or other basic IO manipulators to Message will confuse the
// compiler.
Message& operator <<(BasicNarrowIoManip val) {
*ss_ << val;
return *this;
}
// Instead of 1/0, we want to see true/false for bool values.
Message& operator <<(bool b) {
return *this << (b ? "true" : "false");
}
// These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding.
Message& operator <<(const wchar_t* wide_c_str);
Message& operator <<(wchar_t* wide_c_str);
#if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::std::wstring& wstr);
#endif // GTEST_HAS_STD_WSTRING
#if GTEST_HAS_GLOBAL_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::wstring& wstr);
#endif // GTEST_HAS_GLOBAL_WSTRING
// Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0".
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
std::string GetString() const;
private:
#if GTEST_OS_SYMBIAN
// These are needed as the Nokia Symbian Compiler cannot decide between
// const T& and const T* in a function template. The Nokia compiler _can_
// decide between class template specializations for T and T*, so a
// tr1::type_traits-like is_pointer works, and we can overload on that.
template <typename T>
inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
if (pointer == NULL) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
}
template <typename T>
inline void StreamHelper(internal::false_type /*is_pointer*/,
const T& value) {
// See the comments in Message& operator <<(const T&) above for why
// we need this using statement.
using ::operator <<;
*ss_ << value;
}
#endif // GTEST_OS_SYMBIAN
// We'll hold the text streamed to this object here.
const internal::scoped_ptr< ::std::stringstream> ss_;
// We declare (but don't implement) this to prevent the compiler
// from implementing the assignment operator.
void operator=(const Message&);
};
// Streams a Message to an ostream.
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
return os << sb.GetString();
}
namespace internal {
// Converts a streamable value to an std::string. A NULL pointer is
// converted to "(null)". When the input value is a ::string,
// ::std::string, ::wstring, or ::std::wstring object, each NUL
// character in it is replaced with "\\0".
template <typename T>
std::string StreamableToString(const T& streamable) {
return (Message() << streamable).GetString();
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,487 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: vladl@google.com (Vlad Losev)
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
//
// Here is how you use value-parameterized tests:
#if 0
// To write value-parameterized tests, first you should define a fixture
// class. It is usually derived from testing::TestWithParam<T> (see below for
// another inheritance scheme that's sometimes useful in more complicated
// class hierarchies), where the type of your parameter values.
// TestWithParam<T> is itself derived from testing::Test. T can be any
// copyable type. If it's a raw pointer, you are responsible for managing the
// lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
};
// Then, use the TEST_P macro to define as many parameterized tests
// for this fixture as you want. The _P suffix is for "parameterized"
// or "pattern", whichever you prefer to think.
TEST_P(FooTest, DoesBlah) {
// Inside a test, access the test parameter with the GetParam() method
// of the TestWithParam<T> class:
EXPECT_TRUE(foo.Blah(GetParam()));
...
}
TEST_P(FooTest, HasBlahBlah) {
...
}
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
// case with any set of parameters you want. Google Test defines a number
// of functions for generating test parameters. They return what we call
// (surprise!) parameter generators. Here is a summary of them, which
// are all in the testing namespace:
//
//
// Range(begin, end [, step]) - Yields values {begin, begin+step,
// begin+step+step, ...}. The values do not
// include end. step defaults to 1.
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
// ValuesIn(container) - Yields values from a C-style array, an STL
// ValuesIn(begin,end) container, or an iterator range [begin, end).
// Bool() - Yields sequence {false, true}.
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
// for the math savvy) of the values generated
// by the N generators.
//
// For more details, see comments at the definitions of these functions below
// in this file.
//
// The following statement will instantiate tests from the FooTest test case
// each with parameter values "meeny", "miny", and "moe".
INSTANTIATE_TEST_CASE_P(InstantiationName,
FooTest,
Values("meeny", "miny", "moe"));
// To distinguish different instances of the pattern, (yes, you
// can instantiate it more then once) the first argument to the
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
// actual test case name. Remember to pick unique prefixes for different
// instantiations. The tests from the instantiation above will have
// these names:
//
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
//
// You can use these names in --gtest_filter.
//
// This statement will instantiate all tests from FooTest again, each
// with parameter values "cat" and "dog":
const char* pets[] = {"cat", "dog"};
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
//
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
//
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
// Please also note that generator expressions (including parameters to the
// generators) are evaluated in InitGoogleTest(), after main() has started.
// This allows the user on one hand, to adjust generator parameters in order
// to dynamically determine a set of tests to run and on the other hand,
// give the user a chance to inspect the generated tests with Google Test
// reflection API before RUN_ALL_TESTS() is executed.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
//
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
//
//
// A parameterized test fixture must be derived from testing::Test and from
// testing::WithParamInterface<T>, where T is the type of the parameter
// values. Inheriting from TestWithParam<T> satisfies that requirement because
// TestWithParam<T> inherits from both Test and WithParamInterface. In more
// complicated hierarchies, however, it is occasionally useful to inherit
// separately from Test and WithParamInterface. For example:
class BaseTest : public ::testing::Test {
// You can inherit all the usual members for a non-parameterized test
// fixture here.
};
class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> {
// The usual test fixture members go here too.
};
TEST_F(BaseTest, HasFoo) {
// This is an ordinary non-parameterized test.
}
TEST_P(DerivedTest, DoesBlah) {
// GetParam works just the same here as if you inherit from TestWithParam.
EXPECT_TRUE(foo.Blah(GetParam()));
}
#endif // 0
#include "gtest/internal/gtest-port.h"
#if !GTEST_OS_SYMBIAN
# include <utility>
#endif
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util-generated.h"
#if GTEST_HAS_PARAM_TEST
namespace testing {
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
// parameterized tests. When a parameterized test case is instantiated
// with a particular generator, Google Test creates and runs tests
// for each element in the sequence produced by the generator.
//
// In the following sample, tests from test case FooTest are instantiated
// each three times with parameter values 3, 5, and 8:
//
// class FooTest : public TestWithParam<int> { ... };
//
// TEST_P(FooTest, TestThis) {
// }
// TEST_P(FooTest, TestThat) {
// }
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
//
// Range() returns generators providing sequences of values in a range.
//
// Synopsis:
// Range(start, end)
// - returns a generator producing a sequence of values {start, start+1,
// start+2, ..., }.
// Range(start, end, step)
// - returns a generator producing a sequence of values {start, start+step,
// start+step+step, ..., }.
// Notes:
// * The generated sequences never include end. For example, Range(1, 5)
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
// returns a generator producing {1, 3, 5, 7}.
// * start and end must have the same type. That type may be any integral or
// floating-point type or a user defined type satisfying these conditions:
// * It must be assignable (have operator=() defined).
// * It must have operator+() (operator+(int-compatible type) for
// two-operand version).
// * It must have operator<() defined.
// Elements in the resulting sequences will also have that type.
// * Condition start < end must be satisfied in order for resulting sequences
// to contain any elements.
//
template <typename T, typename IncrementT>
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
return internal::ParamGenerator<T>(
new internal::RangeGenerator<T, IncrementT>(start, end, step));
}
template <typename T>
internal::ParamGenerator<T> Range(T start, T end) {
return Range(start, end, 1);
}
// ValuesIn() function allows generation of tests with parameters coming from
// a container.
//
// Synopsis:
// ValuesIn(const T (&array)[N])
// - returns a generator producing sequences with elements from
// a C-style array.
// ValuesIn(const Container& container)
// - returns a generator producing sequences with elements from
// an STL-style container.
// ValuesIn(Iterator begin, Iterator end)
// - returns a generator producing sequences with elements from
// a range [begin, end) defined by a pair of STL-style iterators. These
// iterators can also be plain C pointers.
//
// Please note that ValuesIn copies the values from the containers
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
//
// Examples:
//
// This instantiates tests from test case StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
//
// This instantiates tests from test case StlStringTest
// each with STL strings with values "a" and "b":
//
// ::std::vector< ::std::string> GetParameterStrings() {
// ::std::vector< ::std::string> v;
// v.push_back("a");
// v.push_back("b");
// return v;
// }
//
// INSTANTIATE_TEST_CASE_P(CharSequence,
// StlStringTest,
// ValuesIn(GetParameterStrings()));
//
//
// This will also instantiate tests from CharTest
// each with parameter values 'a' and 'b':
//
// ::std::list<char> GetParameterChars() {
// ::std::list<char> list;
// list.push_back('a');
// list.push_back('b');
// return list;
// }
// ::std::list<char> l = GetParameterChars();
// INSTANTIATE_TEST_CASE_P(CharSequence2,
// CharTest,
// ValuesIn(l.begin(), l.end()));
//
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end) {
typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
::value_type ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
return ValuesIn(array, array + N);
}
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container) {
return ValuesIn(container.begin(), container.end());
}
// Values() allows generating tests from explicitly specified list of
// parameters.
//
// Synopsis:
// Values(T v1, T v2, ..., T vN)
// - returns a generator producing sequences with elements v1, v2, ..., vN.
//
// For example, this instantiates tests from test case BarTest each
// with values "one", "two", and "three":
//
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
//
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
// Currently, Values() supports from 1 to $n parameters.
//
$range i 1..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
}
]]
// Bool() allows generating tests with parameters in a set of (false, true).
//
// Synopsis:
// Bool()
// - returns a generator producing sequences with elements {false, true}.
//
// It is useful when testing code that depends on Boolean flags. Combinations
// of multiple flags can be tested when several Bool()'s are combined using
// Combine() function.
//
// In the following example all tests in the test case FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
// virtual void SetUp() {
// external_flag = GetParam();
// }
// }
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
# if GTEST_HAS_COMBINE
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
//
// Synopsis:
// Combine(gen1, gen2, ..., genN)
// - returns a generator producing sequences with elements coming from
// the Cartesian product of elements from the sequences generated by
// gen1, gen2, ..., genN. The sequence elements will have a type of
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to $maxtuple arguments. This number is currently limited
// by the maximum number of elements in the tuple implementation used by Google
// Test.
//
// Example:
//
// This will instantiate tests in test case AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// class AnimalTest
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE)));
//
// This will instantiate tests in FlagDependentTest with all variations of two
// Boolean flags:
//
// class FlagDependentTest
// : public testing::TestWithParam<tuple<bool, bool> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam();
// }
// };
//
// TEST_P(FlagDependentTest, TestFeature1) {
// // Test your code using external_flag_1 and external_flag_2 here.
// }
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
// Combine(Bool(), Bool()));
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[typename Generator$j]]>
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
$for j, [[const Generator$j& g$j]]) {
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
$for j, [[g$j]]);
}
]]
# endif // GTEST_HAS_COMBINE
# define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
virtual void TestBody(); \
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
#test_case_name, \
#test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
return 0; \
} \
static int gtest_registering_dummy_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
}; \
int GTEST_TEST_CLASS_NAME_(test_case_name, \
test_name)::gtest_registering_dummy_ = \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
::testing::internal::ParamGenerator<test_case_name::ParamType> \
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
int gtest_##prefix##test_case_name##_dummy_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
#prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_

View file

@ -0,0 +1,855 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Test - The Google C++ Testing Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
//
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr);
//
// A user can teach this function how to print a class type T by
// defining either operator<<() or PrintTo() in the namespace that
// defines T. More specifically, the FIRST defined function in the
// following list will be used (assuming T is defined in namespace
// foo):
//
// 1. foo::PrintTo(const T&, ostream*)
// 2. operator<<(ostream&, const T&) defined in either foo or the
// global namespace.
//
// If none of the above is defined, it will print the debug string of
// the value if it is a protocol buffer, or print the raw bytes in the
// value otherwise.
//
// To aid debugging: when T is a reference type, the address of the
// value is also printed; when T is a (const) char pointer, both the
// pointer value and the NUL-terminated string it points to are
// printed.
//
// We also provide some convenient wrappers:
//
// // Prints a value to a string. For a (const or not) char
// // pointer, the NUL-terminated string (but not the pointer) is
// // printed.
// std::string ::testing::PrintToString(const T& value);
//
// // Prints a value tersely: for a reference type, the referenced
// // value (but not the address) is printed; for a (const or not) char
// // pointer, the NUL-terminated string (but not the pointer) is
// // printed.
// void ::testing::internal::UniversalTersePrint(const T& value, ostream*);
//
// // Prints value using the type inferred by the compiler. The difference
// // from UniversalTersePrint() is that this function prints both the
// // pointer and the NUL-terminated string for a (const or not) char pointer.
// void ::testing::internal::UniversalPrint(const T& value, ostream*);
//
// // Prints the fields of a tuple tersely to a string vector, one
// // element for each field. Tuple support must be enabled in
// // gtest-port.h.
// std::vector<string> UniversalTersePrintTupleFieldsToStrings(
// const Tuple& value);
//
// Known limitation:
//
// The print primitives print the elements of an STL-style container
// using the compiler-inferred type of *iter where iter is a
// const_iterator of the container. When const_iterator is an input
// iterator but not a forward iterator, this inferred type may not
// match value_type, and the print output may be incorrect. In
// practice, this is rarely a problem as for most containers
// const_iterator is a forward iterator. We'll fix this if there's an
// actual need for it. Note that this fix cannot rely on value_type
// being defined as many user-defined container types don't have
// value_type.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#include <ostream> // NOLINT
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-internal.h"
namespace testing {
// Definitions in the 'internal' and 'internal2' name spaces are
// subject to change without notice. DO NOT USE THEM IN USER CODE!
namespace internal2 {
// Prints the given number of bytes in the given object to the given
// ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
size_t count,
::std::ostream* os);
// For selecting which printer to use when a given type has neither <<
// nor PrintTo().
enum TypeKind {
kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type)
kOtherType // anything else
};
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
// by the universal printer to print a value of type T when neither
// operator<< nor PrintTo() is defined for T, where kTypeKind is the
// "kind" of T as defined by enum TypeKind.
template <typename T, TypeKind kTypeKind>
class TypeWithoutFormatter {
public:
// This default version is called when kTypeKind is kOtherType.
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
sizeof(value), os);
}
};
// We print a protobuf using its ShortDebugString() when the string
// doesn't exceed this many characters; otherwise we print it using
// DebugString() for better readability.
const size_t kProtobufOneLinerMaxLength = 50;
template <typename T>
class TypeWithoutFormatter<T, kProtobuf> {
public:
static void PrintValue(const T& value, ::std::ostream* os) {
const ::testing::internal::string short_str = value.ShortDebugString();
const ::testing::internal::string pretty_str =
short_str.length() <= kProtobufOneLinerMaxLength ?
short_str : ("\n" + value.DebugString());
*os << ("<" + pretty_str + ">");
}
};
template <typename T>
class TypeWithoutFormatter<T, kConvertibleToInteger> {
public:
// Since T has no << operator or PrintTo() but can be implicitly
// converted to BiggestInt, we print it as a BiggestInt.
//
// Most likely T is an enum type (either named or unnamed), in which
// case printing it as an integer is the desired behavior. In case
// T is not an enum, printing it as an integer is the best we can do
// given that it has no user-defined printer.
static void PrintValue(const T& value, ::std::ostream* os) {
const internal::BiggestInt kBigInt = value;
*os << kBigInt;
}
};
// Prints the given value to the given ostream. If the value is a
// protocol message, its debug string is printed; if it's an enum or
// of a type implicitly convertible to BiggestInt, it's printed as an
// integer; otherwise the bytes in the value are printed. This is
// what UniversalPrinter<T>::Print() does when it knows nothing about
// type T and T has neither << operator nor PrintTo().
//
// A user can override this behavior for a class type Foo by defining
// a << operator in the namespace where Foo is defined.
//
// We put this operator in namespace 'internal2' instead of 'internal'
// to simplify the implementation, as much code in 'internal' needs to
// use << in STL, which would conflict with our own << were it defined
// in 'internal'.
//
// Note that this operator<< takes a generic std::basic_ostream<Char,
// CharTraits> type instead of the more restricted std::ostream. If
// we define it to take an std::ostream instead, we'll get an
// "ambiguous overloads" compiler error when trying to print a type
// Foo that supports streaming to std::basic_ostream<Char,
// CharTraits>, as the compiler cannot tell whether
// operator<<(std::ostream&, const T&) or
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
// specific.
template <typename Char, typename CharTraits, typename T>
::std::basic_ostream<Char, CharTraits>& operator<<(
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
TypeWithoutFormatter<T,
(internal::IsAProtocolMessage<T>::value ? kProtobuf :
internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
return os;
}
} // namespace internal2
} // namespace testing
// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
// magic needed for implementing UniversalPrinter won't work.
namespace testing_internal {
// Used to print a value that is not an STL-style container when the
// user doesn't define PrintTo() for it.
template <typename T>
void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
// With the following statement, during unqualified name lookup,
// testing::internal2::operator<< appears as if it was declared in
// the nearest enclosing namespace that contains both
// ::testing_internal and ::testing::internal2, i.e. the global
// namespace. For more details, refer to the C++ Standard section
// 7.3.4-1 [namespace.udir]. This allows us to fall back onto
// testing::internal2::operator<< in case T doesn't come with a <<
// operator.
//
// We cannot write 'using ::testing::internal2::operator<<;', which
// gcc 3.3 fails to compile due to a compiler bug.
using namespace ::testing::internal2; // NOLINT
// Assuming T is defined in namespace foo, in the next statement,
// the compiler will consider all of:
//
// 1. foo::operator<< (thanks to Koenig look-up),
// 2. ::operator<< (as the current namespace is enclosed in ::),
// 3. testing::internal2::operator<< (thanks to the using statement above).
//
// The operator<< whose type matches T best will be picked.
//
// We deliberately allow #2 to be a candidate, as sometimes it's
// impossible to define #1 (e.g. when foo is ::std, defining
// anything in it is undefined behavior unless you are a compiler
// vendor.).
*os << value;
}
} // namespace testing_internal
namespace testing {
namespace internal {
// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given
// value to the given ostream. The caller must ensure that
// 'ostream_ptr' is not NULL, or the behavior is undefined.
//
// We define UniversalPrinter as a class template (as opposed to a
// function template), as we need to partially specialize it for
// reference types, which cannot be done with function templates.
template <typename T>
class UniversalPrinter;
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
template <typename C>
void DefaultPrintTo(IsContainer /* dummy */,
false_type /* is not a pointer */,
const C& container, ::std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
size_t count = 0;
for (typename C::const_iterator it = container.begin();
it != container.end(); ++it, ++count) {
if (count > 0) {
*os << ',';
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
break;
}
}
*os << ' ';
// We cannot call PrintTo(*it, os) here as PrintTo() doesn't
// handle *it being a native array.
internal::UniversalPrint(*it, os);
}
if (count > 0) {
*os << ' ';
}
*os << '}';
}
// Used to print a pointer that is neither a char pointer nor a member
// pointer, when the user doesn't define PrintTo() for it. (A member
// variable pointer or member function pointer doesn't really point to
// a location in the address space. Their representation is
// implementation-defined. Therefore they will be printed as raw
// bytes.)
template <typename T>
void DefaultPrintTo(IsNotContainer /* dummy */,
true_type /* is a pointer */,
T* p, ::std::ostream* os) {
if (p == NULL) {
*os << "NULL";
} else {
// C++ doesn't allow casting from a function pointer to any object
// pointer.
//
// IsTrue() silences warnings: "Condition is always true",
// "unreachable code".
if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {
// T is not a function type. We just call << to print p,
// relying on ADL to pick up user-defined << for their pointer
// types, if any.
*os << p;
} else {
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*. However, we cannot cast it to const void* directly,
// even using reinterpret_cast, as earlier versions of gcc
// (e.g. 3.4.5) cannot compile the cast when p is a function
// pointer. Casting to UInt64 first solves the problem.
*os << reinterpret_cast<const void*>(
reinterpret_cast<internal::UInt64>(p));
}
}
}
// Used to print a non-container, non-pointer value when the user
// doesn't define PrintTo() for it.
template <typename T>
void DefaultPrintTo(IsNotContainer /* dummy */,
false_type /* is not a pointer */,
const T& value, ::std::ostream* os) {
::testing_internal::DefaultPrintNonContainerTo(value, os);
}
// Prints the given value using the << operator if it has one;
// otherwise prints the bytes in it. This is what
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized
// or overloaded for type T.
//
// A user can override this behavior for a class type Foo by defining
// an overload of PrintTo() in the namespace where Foo is defined. We
// give the user this option as sometimes defining a << operator for
// Foo is not desirable (e.g. the coding style may prevent doing it,
// or there is already a << operator but it doesn't do what the user
// wants).
template <typename T>
void PrintTo(const T& value, ::std::ostream* os) {
// DefaultPrintTo() is overloaded. The type of its first two
// arguments determine which version will be picked. If T is an
// STL-style container, the version for container will be called; if
// T is a pointer, the pointer version will be called; otherwise the
// generic version will be called.
//
// Note that we check for container types here, prior to we check
// for protocol message types in our operator<<. The rationale is:
//
// For protocol messages, we want to give people a chance to
// override Google Mock's format by defining a PrintTo() or
// operator<<. For STL containers, other formats can be
// incompatible with Google Mock's format for the container
// elements; therefore we check for container types here to ensure
// that our format is used.
//
// The second argument of DefaultPrintTo() is needed to bypass a bug
// in Symbian's C++ compiler that prevents it from picking the right
// overload between:
//
// PrintTo(const T& x, ...);
// PrintTo(T* x, ...);
DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
}
// The following list of PrintTo() overloads tells
// UniversalPrinter<T>::Print() how to print standard types (built-in
// types, strings, plain arrays, and pointers).
// Overloads for various char types.
GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os);
GTEST_API_ void PrintTo(signed char c, ::std::ostream* os);
inline void PrintTo(char c, ::std::ostream* os) {
// When printing a plain char, we always treat it as unsigned. This
// way, the output won't be affected by whether the compiler thinks
// char is signed or not.
PrintTo(static_cast<unsigned char>(c), os);
}
// Overloads for other simple built-in types.
inline void PrintTo(bool x, ::std::ostream* os) {
*os << (x ? "true" : "false");
}
// Overload for wchar_t type.
// Prints a wchar_t as a symbol if it is printable or as its internal
// code otherwise and also as its decimal code (except for L'\0').
// The L'\0' char is printed as "L'\\0'". The decimal code is printed
// as signed integer when wchar_t is implemented by the compiler
// as a signed type and is printed as an unsigned integer when wchar_t
// is implemented as an unsigned type.
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
// Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
inline void PrintTo(char* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char*>(s), os);
}
// signed/unsigned char is often used for representing binary data, so
// we print pointers to it as void* to be safe.
inline void PrintTo(const signed char* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const void*>(s), os);
}
inline void PrintTo(signed char* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const void*>(s), os);
}
inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const void*>(s), os);
}
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const void*>(s), os);
}
// MSVC can be configured to define wchar_t as a typedef of unsigned
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
// type. When wchar_t is a typedef, defining an overload for const
// wchar_t* would cause unsigned short* be printed as a wide string,
// possibly causing invalid memory accesses.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Overloads for wide C strings
GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
inline void PrintTo(wchar_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const wchar_t*>(s), os);
}
#endif
// Overload for C arrays. Multi-dimensional arrays are printed
// properly.
// Prints the given number of elements in an array, without printing
// the curly braces.
template <typename T>
void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
UniversalPrint(a[0], os);
for (size_t i = 1; i != count; i++) {
*os << ", ";
UniversalPrint(a[i], os);
}
}
// Overloads for ::string and ::std::string.
#if GTEST_HAS_GLOBAL_STRING
GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os);
inline void PrintTo(const ::string& s, ::std::ostream* os) {
PrintStringTo(s, os);
}
#endif // GTEST_HAS_GLOBAL_STRING
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
PrintStringTo(s, os);
}
// Overloads for ::wstring and ::std::wstring.
#if GTEST_HAS_GLOBAL_WSTRING
GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
PrintWideStringTo(s, os);
}
#endif // GTEST_HAS_GLOBAL_WSTRING
#if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
PrintWideStringTo(s, os);
}
#endif // GTEST_HAS_STD_WSTRING
#if GTEST_HAS_TR1_TUPLE
// Overload for ::std::tr1::tuple. Needed for printing function arguments,
// which are packed as tuples.
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
template <typename T>
void PrintTupleTo(const T& t, ::std::ostream* os);
// Overloaded PrintTo() for tuples of various arities. We support
// tuples of up-to 10 fields. The following implementation works
// regardless of whether tr1::tuple is implemented using the
// non-standard variadic template feature or not.
inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1>
void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2>
void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3, typename T4>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
::std::ostream* os) {
PrintTupleTo(t, os);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
void PrintTo(
const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
::std::ostream* os) {
PrintTupleTo(t, os);
}
#endif // GTEST_HAS_TR1_TUPLE
// Overload for std::pair.
template <typename T1, typename T2>
void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) {
*os << '(';
// We cannot use UniversalPrint(value.first, os) here, as T1 may be
// a reference type. The same for printing value.second.
UniversalPrinter<T1>::Print(value.first, os);
*os << ", ";
UniversalPrinter<T2>::Print(value.second, os);
*os << ')';
}
// Implements printing a non-reference type T by letting the compiler
// pick the right overload of PrintTo() for T.
template <typename T>
class UniversalPrinter {
public:
// MSVC warns about adding const to a function type, so we want to
// disable the warning.
#ifdef _MSC_VER
# pragma warning(push) // Saves the current warning state.
# pragma warning(disable:4180) // Temporarily disables warning 4180.
#endif // _MSC_VER
// Note: we deliberately don't call this PrintTo(), as that name
// conflicts with ::testing::internal::PrintTo in the body of the
// function.
static void Print(const T& value, ::std::ostream* os) {
// By default, ::testing::internal::PrintTo() is used for printing
// the value.
//
// Thanks to Koenig look-up, if T is a class and has its own
// PrintTo() function defined in its namespace, that function will
// be visible here. Since it is more specific than the generic ones
// in ::testing::internal, it will be picked by the compiler in the
// following statement - exactly what we want.
PrintTo(value, os);
}
#ifdef _MSC_VER
# pragma warning(pop) // Restores the warning state.
#endif // _MSC_VER
};
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
template <typename T>
void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
if (len == 0) {
*os << "{}";
} else {
*os << "{ ";
const size_t kThreshold = 18;
const size_t kChunkSize = 8;
// If the array has more than kThreshold elements, we'll have to
// omit some details by printing only the first and the last
// kChunkSize elements.
// TODO(wan@google.com): let the user control the threshold using a flag.
if (len <= kThreshold) {
PrintRawArrayTo(begin, len, os);
} else {
PrintRawArrayTo(begin, kChunkSize, os);
*os << ", ..., ";
PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
}
*os << " }";
}
}
// This overload prints a (const) char array compactly.
GTEST_API_ void UniversalPrintArray(
const char* begin, size_t len, ::std::ostream* os);
// This overload prints a (const) wchar_t array compactly.
GTEST_API_ void UniversalPrintArray(
const wchar_t* begin, size_t len, ::std::ostream* os);
// Implements printing an array type T[N].
template <typename T, size_t N>
class UniversalPrinter<T[N]> {
public:
// Prints the given array, omitting some elements when there are too
// many.
static void Print(const T (&a)[N], ::std::ostream* os) {
UniversalPrintArray(a, N, os);
}
};
// Implements printing a reference type T&.
template <typename T>
class UniversalPrinter<T&> {
public:
// MSVC warns about adding const to a function type, so we want to
// disable the warning.
#ifdef _MSC_VER
# pragma warning(push) // Saves the current warning state.
# pragma warning(disable:4180) // Temporarily disables warning 4180.
#endif // _MSC_VER
static void Print(const T& value, ::std::ostream* os) {
// Prints the address of the value. We use reinterpret_cast here
// as static_cast doesn't compile when T is a function type.
*os << "@" << reinterpret_cast<const void*>(&value) << " ";
// Then prints the value itself.
UniversalPrint(value, os);
}
#ifdef _MSC_VER
# pragma warning(pop) // Restores the warning state.
#endif // _MSC_VER
};
// Prints a value tersely: for a reference type, the referenced value
// (but not the address) is printed; for a (const) char pointer, the
// NUL-terminated string (but not the pointer) is printed.
template <typename T>
class UniversalTersePrinter {
public:
static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os);
}
};
template <typename T>
class UniversalTersePrinter<T&> {
public:
static void Print(const T& value, ::std::ostream* os) {
UniversalPrint(value, os);
}
};
template <typename T, size_t N>
class UniversalTersePrinter<T[N]> {
public:
static void Print(const T (&value)[N], ::std::ostream* os) {
UniversalPrinter<T[N]>::Print(value, os);
}
};
template <>
class UniversalTersePrinter<const char*> {
public:
static void Print(const char* str, ::std::ostream* os) {
if (str == NULL) {
*os << "NULL";
} else {
UniversalPrint(string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char*> {
public:
static void Print(char* str, ::std::ostream* os) {
UniversalTersePrinter<const char*>::Print(str, os);
}
};
#if GTEST_HAS_STD_WSTRING
template <>
class UniversalTersePrinter<const wchar_t*> {
public:
static void Print(const wchar_t* str, ::std::ostream* os) {
if (str == NULL) {
*os << "NULL";
} else {
UniversalPrint(::std::wstring(str), os);
}
}
};
#endif
template <>
class UniversalTersePrinter<wchar_t*> {
public:
static void Print(wchar_t* str, ::std::ostream* os) {
UniversalTersePrinter<const wchar_t*>::Print(str, os);
}
};
template <typename T>
void UniversalTersePrint(const T& value, ::std::ostream* os) {
UniversalTersePrinter<T>::Print(value, os);
}
// Prints a value using the type inferred by the compiler. The
// difference between this and UniversalTersePrint() is that for a
// (const) char pointer, this prints both the pointer and the
// NUL-terminated string.
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os) {
// A workarond for the bug in VC++ 7.1 that prevents us from instantiating
// UniversalPrinter with T directly.
typedef T T1;
UniversalPrinter<T1>::Print(value, os);
}
#if GTEST_HAS_TR1_TUPLE
typedef ::std::vector<string> Strings;
// This helper template allows PrintTo() for tuples and
// UniversalTersePrintTupleFieldsToStrings() to be defined by
// induction on the number of tuple fields. The idea is that
// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
// fields in tuple t, and can be defined in terms of
// TuplePrefixPrinter<N - 1>.
// The inductive case.
template <size_t N>
struct TuplePrefixPrinter {
// Prints the first N fields of a tuple.
template <typename Tuple>
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
*os << ", ";
UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type>
::Print(::std::tr1::get<N - 1>(t), os);
}
// Tersely prints the first N fields of a tuple to a string vector,
// one element for each field.
template <typename Tuple>
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
::std::stringstream ss;
UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss);
strings->push_back(ss.str());
}
};
// Base cases.
template <>
struct TuplePrefixPrinter<0> {
template <typename Tuple>
static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
template <typename Tuple>
static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
};
// We have to specialize the entire TuplePrefixPrinter<> class
// template here, even though the definition of
// TersePrintPrefixToStrings() is the same as the generic version, as
// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't
// support specializing a method template of a class template.
template <>
struct TuplePrefixPrinter<1> {
template <typename Tuple>
static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>::
Print(::std::tr1::get<0>(t), os);
}
template <typename Tuple>
static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
::std::stringstream ss;
UniversalTersePrint(::std::tr1::get<0>(t), &ss);
strings->push_back(ss.str());
}
};
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
template <typename T>
void PrintTupleTo(const T& t, ::std::ostream* os) {
*os << "(";
TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>::
PrintPrefixTo(t, os);
*os << ")";
}
// Prints the fields of a tuple tersely to a string vector, one
// element for each field. See the comment before
// UniversalTersePrint() for how we define "tersely".
template <typename Tuple>
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
Strings result;
TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>::
TersePrintPrefixToStrings(value, &result);
return result;
}
#endif // GTEST_HAS_TR1_TUPLE
} // namespace internal
template <typename T>
::std::string PrintToString(const T& value) {
::std::stringstream ss;
internal::UniversalTersePrinter<T>::Print(value, &ss);
return ss.str();
}
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_

View file

@ -0,0 +1,232 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Utilities for testing Google Test itself and code that uses Google Test
// (e.g. frameworks built on top of Google Test).
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#include "gtest/gtest.h"
namespace testing {
// This helper class can be used to mock out Google Test failure reporting
// so that we can test Google Test or code that builds on Google Test.
//
// An object of this class appends a TestPartResult object to the
// TestPartResultArray object given in the constructor whenever a Google Test
// failure is reported. It can either intercept only failures that are
// generated in the same thread that created this object or it can intercept
// all generated failures. The scope of this mock object can be controlled with
// the second argument to the two arguments constructor.
class GTEST_API_ ScopedFakeTestPartResultReporter
: public TestPartResultReporterInterface {
public:
// The two possible mocking modes of this object.
enum InterceptMode {
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures.
INTERCEPT_ALL_THREADS // Intercepts all failures.
};
// The c'tor sets this object as the test part result reporter used
// by Google Test. The 'result' parameter specifies where to report the
// results. This reporter will only catch failures generated in the current
// thread. DEPRECATED
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
// Same as above, but you can choose the interception scope of this object.
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
TestPartResultArray* result);
// The d'tor restores the previous test part result reporter.
virtual ~ScopedFakeTestPartResultReporter();
// Appends the TestPartResult object to the TestPartResultArray
// received in the constructor.
//
// This method is from the TestPartResultReporterInterface
// interface.
virtual void ReportTestPartResult(const TestPartResult& result);
private:
void Init();
const InterceptMode intercept_mode_;
TestPartResultReporterInterface* old_reporter_;
TestPartResultArray* const result_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
};
namespace internal {
// A helper class for implementing EXPECT_FATAL_FAILURE() and
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given
// TestPartResultArray contains exactly one failure that has the given
// type and contains the given substring. If that's not the case, a
// non-fatal failure will be generated.
class GTEST_API_ SingleFailureChecker {
public:
// The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results,
TestPartResult::Type type,
const string& substr);
~SingleFailureChecker();
private:
const TestPartResultArray* const results_;
const TestPartResult::Type type_;
const string substr_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
};
} // namespace internal
} // namespace testing
// A set of macros for testing Google Test assertions or code that's expected
// to generate Google Test fatal failures. It verifies that the given
// statement will cause exactly one fatal Google Test failure with 'substr'
// being part of the failure message.
//
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
// affects and considers failures generated in the current thread and
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
//
// The verification of the assertion is done correctly even when the statement
// throws an exception or aborts the current function.
//
// Known restrictions:
// - 'statement' cannot reference local non-static variables or
// non-static members of the current object.
// - 'statement' cannot return a value.
// - You cannot stream a failure message to this macro.
//
// Note that even though the implementations of the following two
// macros are much alike, we cannot refactor them to use a common
// helper macro, due to some peculiarity in how the preprocessor
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
// gtest_unittest.cc will fail to compile if we do that.
#define EXPECT_FATAL_FAILURE(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
} while (::testing::internal::AlwaysFalse())
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ALL_THREADS, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
} while (::testing::internal::AlwaysFalse())
// A macro for testing Google Test assertions or code that's expected to
// generate Google Test non-fatal failures. It asserts that the given
// statement will cause exactly one non-fatal Google Test failure with 'substr'
// being part of the failure message.
//
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
// affects and considers failures generated in the current thread and
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
//
// 'statement' is allowed to reference local variables and members of
// the current object.
//
// The verification of the assertion is done correctly even when the statement
// throws an exception or aborts the current function.
//
// Known restrictions:
// - You cannot stream a failure message to this macro.
//
// Note that even though the implementations of the following two
// macros are much alike, we cannot refactor them to use a common
// helper macro, due to some peculiarity in how the preprocessor
// works. If we do that, the code won't compile when the user gives
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
// expands to code containing an unprotected comma. The
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
// catches that.
//
// For the same reason, we have to write
// if (::testing::internal::AlwaysTrue()) { statement; }
// instead of
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
// to avoid an MSVC warning on unreachable code.
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
} while (::testing::internal::AlwaysFalse())
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
&gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
} while (::testing::internal::AlwaysFalse())
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_

View file

@ -0,0 +1,179 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
namespace testing {
// A copyable object representing the result of a test part (i.e. an
// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()).
//
// Don't inherit from TestPartResult as its destructor is not virtual.
class GTEST_API_ TestPartResult {
public:
// The possible outcomes of a test part (i.e. an assertion or an
// explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
enum Type {
kSuccess, // Succeeded.
kNonFatalFailure, // Failed but the test can continue.
kFatalFailure // Failed and the test should be terminated.
};
// C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
// TestPartResult object.
TestPartResult(Type a_type,
const char* a_file_name,
int a_line_number,
const char* a_message)
: type_(a_type),
file_name_(a_file_name == NULL ? "" : a_file_name),
line_number_(a_line_number),
summary_(ExtractSummary(a_message)),
message_(a_message) {
}
// Gets the outcome of the test part.
Type type() const { return type_; }
// Gets the name of the source file where the test part took place, or
// NULL if it's unknown.
const char* file_name() const {
return file_name_.empty() ? NULL : file_name_.c_str();
}
// Gets the line in the source file where the test part took place,
// or -1 if it's unknown.
int line_number() const { return line_number_; }
// Gets the summary of the failure message.
const char* summary() const { return summary_.c_str(); }
// Gets the message associated with the test part.
const char* message() const { return message_.c_str(); }
// Returns true iff the test part passed.
bool passed() const { return type_ == kSuccess; }
// Returns true iff the test part failed.
bool failed() const { return type_ != kSuccess; }
// Returns true iff the test part non-fatally failed.
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
// Returns true iff the test part fatally failed.
bool fatally_failed() const { return type_ == kFatalFailure; }
private:
Type type_;
// Gets the summary of the failure message by omitting the stack
// trace in it.
static std::string ExtractSummary(const char* message);
// The name of the source file where the test part took place, or
// "" if the source file is unknown.
std::string file_name_;
// The line in the source file where the test part took place, or -1
// if the line number is unknown.
int line_number_;
std::string summary_; // The test failure summary.
std::string message_; // The test failure message.
};
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
// An array of TestPartResult objects.
//
// Don't inherit from TestPartResultArray as its destructor is not
// virtual.
class GTEST_API_ TestPartResultArray {
public:
TestPartResultArray() {}
// Appends the given TestPartResult to the array.
void Append(const TestPartResult& result);
// Returns the TestPartResult at the given index (0-based).
const TestPartResult& GetTestPartResult(int index) const;
// Returns the number of TestPartResult objects in the array.
int size() const;
private:
std::vector<TestPartResult> array_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
};
// This interface knows how to report a test part result.
class TestPartResultReporterInterface {
public:
virtual ~TestPartResultReporterInterface() {}
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
};
namespace internal {
// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
// statement generates new fatal failures. To do so it registers itself as the
// current test part result reporter. Besides checking if fatal failures were
// reported, it only delegates the reporting to the former result reporter.
// The original result reporter is restored in the destructor.
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
class GTEST_API_ HasNewFatalFailureHelper
: public TestPartResultReporterInterface {
public:
HasNewFatalFailureHelper();
virtual ~HasNewFatalFailureHelper();
virtual void ReportTestPartResult(const TestPartResult& result);
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
private:
bool has_new_fatal_failure_;
TestPartResultReporterInterface* original_reporter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
};
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_

View file

@ -0,0 +1,259 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
// This header implements typed tests and type-parameterized tests.
// Typed (aka type-driven) tests repeat the same test for types in a
// list. You must know which types you want to test with when writing
// typed tests. Here's how you do it:
#if 0
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
public:
...
typedef std::list<T> List;
static T shared_;
T value_;
};
// Next, associate a list of types with the test case, which will be
// repeated for each type in the list. The typedef is necessary for
// the macro to parse correctly.
typedef testing::Types<char, int, unsigned int> MyTypes;
TYPED_TEST_CASE(FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
// TYPED_TEST_CASE(FooTest, int);
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
// tests for this test case as you want.
TYPED_TEST(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
// Since we are inside a derived class template, C++ requires use to
// visit the members of FooTest via 'this'.
TypeParam n = this->value_;
// To visit static members of the fixture, add the TestFixture::
// prefix.
n += TestFixture::shared_;
// To refer to typedefs in the fixture, add the "typename
// TestFixture::" prefix.
typename TestFixture::List values;
values.push_back(n);
...
}
TYPED_TEST(FooTest, HasPropertyA) { ... }
#endif // 0
// Type-parameterized tests are abstract test patterns parameterized
// by a type. Compared with typed tests, type-parameterized tests
// allow you to define the test pattern without knowing what the type
// parameters are. The defined pattern can be instantiated with
// different types any number of times, in any number of translation
// units.
//
// If you are designing an interface or concept, you can define a
// suite of type-parameterized tests to verify properties that any
// valid implementation of the interface/concept should have. Then,
// each implementation can easily instantiate the test suite to verify
// that it conforms to the requirements, without having to write
// similar tests repeatedly. Here's an example:
#if 0
// First, define a fixture class template. It should be parameterized
// by a type. Remember to derive it from testing::Test.
template <typename T>
class FooTest : public testing::Test {
...
};
// Next, declare that you will define a type-parameterized test case
// (the _P suffix is for "parameterized" or "pattern", whichever you
// prefer):
TYPED_TEST_CASE_P(FooTest);
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
// for this type-parameterized test case as you want.
TYPED_TEST_P(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
TypeParam n = 0;
...
}
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
// Now the tricky part: you need to register all test patterns before
// you can instantiate them. The first argument of the macro is the
// test case name; the rest are the names of the tests in this test
// case.
REGISTER_TYPED_TEST_CASE_P(FooTest,
DoesBlah, HasPropertyA);
// Finally, you are free to instantiate the pattern with the types you
// want. If you put the above code in a header file, you can #include
// it in multiple C++ source files and instantiate it multiple times.
//
// To distinguish different instances of the pattern, the first
// argument to the INSTANTIATE_* macro is a prefix that will be added
// to the actual test case name. Remember to pick unique prefixes for
// different instances.
typedef testing::Types<char, int, unsigned int> MyTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
#endif // 0
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-type-util.h"
// Implements typed tests.
#if GTEST_HAS_TYPED_TEST
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the typedef for the type parameters of the
// given test case.
# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
# define TYPED_TEST_CASE(CaseName, Types) \
typedef ::testing::internal::TypeList< Types >::type \
GTEST_TYPE_PARAMS_(CaseName)
# define TYPED_TEST(CaseName, TestName) \
template <typename gtest_TypeParam_> \
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
: public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel< \
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
"", #CaseName, #TestName, 0); \
template <typename gtest_TypeParam_> \
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
#endif // GTEST_HAS_TYPED_TEST
// Implements type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the namespace name that the type-parameterized tests for
// the given type-parameterized test case are defined in. The exact
// name of the namespace is subject to change without notice.
# define GTEST_CASE_NAMESPACE_(TestCaseName) \
gtest_case_##TestCaseName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the variable used to remember the names of
// the defined tests in the given test case.
# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
gtest_typed_test_case_p_state_##TestCaseName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
//
// Expands to the name of the variable used to remember the names of
// the registered tests in the given test case.
# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
gtest_registered_test_names_##TestCaseName##_
// The variables defined in the type-parameterized test macros are
// static as typically these macros are used in a .h file that can be
// #included in multiple translation units linked together.
# define TYPED_TEST_CASE_P(CaseName) \
static ::testing::internal::TypedTestCasePState \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
# define TYPED_TEST_P(CaseName, TestName) \
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
template <typename gtest_TypeParam_> \
class TestName : public CaseName<gtest_TypeParam_> { \
private: \
typedef CaseName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
virtual void TestBody(); \
}; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
__FILE__, __LINE__, #CaseName, #TestName); \
} \
template <typename gtest_TypeParam_> \
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
__FILE__, __LINE__, #__VA_ARGS__)
// The 'Types' template argument below must have spaces around it
// since some compilers may choke on '>>' when passing a template
// instance (e.g. Types<int>)
# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTestCase<CaseName, \
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
::testing::internal::TypeList< Types >::type>::Register(\
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,358 @@
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h.
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion
// macros:
//
// ASSERT_PRED_FORMAT1(pred_format, v1)
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
// ...
//
// where pred_format is a function or functor that takes n (in the
// case of ASSERT_PRED_FORMATn) values and their source expression
// text, and returns a testing::AssertionResult. See the definition
// of ASSERT_EQ in gtest.h for an example.
//
// If you don't care about formatting, you can use the more
// restrictive version:
//
// ASSERT_PRED1(pred, v1)
// ASSERT_PRED2(pred, v1, v2)
// ...
//
// where pred is an n-ary function or functor that returns bool,
// and the values v1, v2, ..., must support the << operator for
// streaming to std::ostream.
//
// We also define the EXPECT_* variations.
//
// For now we only support predicates whose arity is at most 5.
// Please email googletestframework@googlegroups.com if you need
// support for higher arities.
// GTEST_ASSERT_ is the basic statement to which all of the assertions
// in this file reduce. Don't use this in your code.
#define GTEST_ASSERT_(expression, on_failure) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar = (expression)) \
; \
else \
on_failure(gtest_ar.failure_message())
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
template <typename Pred,
typename T1>
AssertionResult AssertPred1Helper(const char* pred_text,
const char* e1,
Pred pred,
const T1& v1) {
if (pred(v1)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
// Don't use this in your code.
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
GTEST_ASSERT_(pred_format(#v1, v1), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
#define GTEST_PRED1_(pred, v1, on_failure)\
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
#v1, \
pred, \
v1), on_failure)
// Unary predicate assertion macros.
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2>
AssertionResult AssertPred2Helper(const char* pred_text,
const char* e1,
const char* e2,
Pred pred,
const T1& v1,
const T2& v2) {
if (pred(v1, v2)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
// Don't use this in your code.
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
#v1, \
#v2, \
pred, \
v1, \
v2), on_failure)
// Binary predicate assertion macros.
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \
GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3>
AssertionResult AssertPred3Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3) {
if (pred(v1, v2, v3)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
// Don't use this in your code.
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
#v1, \
#v2, \
#v3, \
pred, \
v1, \
v2, \
v3), on_failure)
// Ternary predicate assertion macros.
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \
GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4>
AssertionResult AssertPred4Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4) {
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ", "
<< e4 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3
<< "\n" << e4 << " evaluates to " << v4;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
// Don't use this in your code.
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
pred, \
v1, \
v2, \
v3, \
v4), on_failure)
// 4-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
AssertionResult AssertPred5Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
const char* e5,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4,
const T5& v5) {
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
return AssertionFailure() << pred_text << "("
<< e1 << ", "
<< e2 << ", "
<< e3 << ", "
<< e4 << ", "
<< e5 << ") evaluates to false, where"
<< "\n" << e1 << " evaluates to " << v1
<< "\n" << e2 << " evaluates to " << v2
<< "\n" << e3 << " evaluates to " << v3
<< "\n" << e4 << " evaluates to " << v4
<< "\n" << e5 << " evaluates to " << v5;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
// Don't use this in your code.
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
#v5, \
pred, \
v1, \
v2, \
v3, \
v4, \
v5), on_failure)
// 5-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_

View file

@ -0,0 +1,58 @@
// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
//
// Google C++ Testing Framework definitions useful in production code.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
// When you need to test the private or protected members of a class,
// use the FRIEND_TEST macro to declare your tests as friends of the
// class. For example:
//
// class MyClass {
// private:
// void MyMethod();
// FRIEND_TEST(MyClassTest, MyMethod);
// };
//
// class MyClassTest : public testing::Test {
// // ...
// };
//
// TEST_F(MyClassTest, MyMethod) {
// // Can call MyClass::MyMethod() here.
// }
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_

View file

@ -0,0 +1,319 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file defines internal utilities needed for implementing
// death tests. They are subject to change without notice.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#include "gtest/internal/gtest-internal.h"
#include <stdio.h>
namespace testing {
namespace internal {
GTEST_DECLARE_string_(internal_run_death_test);
// Names of the flags (needed for parsing Google Test flags).
const char kDeathTestStyleFlag[] = "death_test_style";
const char kDeathTestUseFork[] = "death_test_use_fork";
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
#if GTEST_HAS_DEATH_TEST
// DeathTest is a class that hides much of the complexity of the
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
// returns a concrete class that depends on the prevailing death test
// style, as defined by the --gtest_death_test_style and/or
// --gtest_internal_run_death_test flags.
// In describing the results of death tests, these terms are used with
// the corresponding definitions:
//
// exit status: The integer exit information in the format specified
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
public:
// Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example,
// if the gtest_death_test_style flag is set to an invalid value.
// The LastMessage method will return a more detailed message in that
// case. Otherwise, the DeathTest pointer pointed to by the "test"
// argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test.
static bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
DeathTest();
virtual ~DeathTest() { }
// A helper class that aborts a death test when it's deleted.
class ReturnSentinel {
public:
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
private:
DeathTest* const test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
} GTEST_ATTRIBUTE_UNUSED_;
// An enumeration of possible roles that may be taken when a death
// test is encountered. EXECUTE means that the death test logic should
// be executed immediately. OVERSEE means that the program should prepare
// the appropriate environment for a child process to execute the death
// test, then wait for it to complete.
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
// An enumeration of the three reasons that a test might be aborted.
enum AbortReason {
TEST_ENCOUNTERED_RETURN_STATEMENT,
TEST_THREW_EXCEPTION,
TEST_DID_NOT_DIE
};
// Assumes one of the above roles.
virtual TestRole AssumeRole() = 0;
// Waits for the death test to finish and returns its status.
virtual int Wait() = 0;
// Returns true if the death test passed; that is, the test process
// exited during the test, its exit status matches a user-supplied
// predicate, and its stderr output matches a user-supplied regular
// expression.
// The user-supplied predicate may be a macro expression rather
// than a function pointer or functor, or else Wait and Passed could
// be combined.
virtual bool Passed(bool exit_status_ok) = 0;
// Signals that the death test did not die as expected.
virtual void Abort(AbortReason reason) = 0;
// Returns a human-readable outcome message regarding the outcome of
// the last death test.
static const char* LastMessage();
static void set_last_death_test_message(const std::string& message);
private:
// A string containing a description of the outcome of the last death test.
static std::string last_death_test_message_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
};
// Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory {
public:
virtual ~DeathTestFactory() { }
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test) = 0;
};
// A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory {
public:
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
};
// Returns true if exit_status describes a process that was terminated
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (const ::std::exception& gtest_exception) { \
fprintf(\
stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
gtest_exception.what()); \
fflush(stderr); \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
} catch (...) { \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
}
# else
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
# endif
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::DeathTest* gtest_dt; \
if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
__FILE__, __LINE__, &gtest_dt)) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
if (gtest_dt != NULL) { \
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
gtest_dt_ptr(gtest_dt); \
switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
default: \
break; \
} \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
fail(::testing::internal::DeathTest::LastMessage())
// The symbol "fail" here expands to something into which a message
// can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
// NDEBUG mode. In this case we need the statements to be executed, the regex is
// ignored, and the macro must accept a streamed message even though the message
// is never printed.
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else \
::testing::Message()
// A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag {
public:
InternalRunDeathTestFlag(const std::string& a_file,
int a_line,
int an_index,
int a_write_fd)
: file_(a_file), line_(a_line), index_(an_index),
write_fd_(a_write_fd) {}
~InternalRunDeathTestFlag() {
if (write_fd_ >= 0)
posix::Close(write_fd_);
}
const std::string& file() const { return file_; }
int line() const { return line_; }
int index() const { return index_; }
int write_fd() const { return write_fd_; }
private:
std::string file_;
int line_;
int index_;
int write_fd_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
};
// Returns a newly created InternalRunDeathTestFlag object with fields
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
// the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
#else // GTEST_HAS_DEATH_TEST
// This macro is used for implementing macros such as
// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
// death tests are not supported. Those macros must compile on such systems
// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
// systems that support death tests. This allows one to write such a macro
// on a system that does not support death tests and be sure that it will
// compile on a death-test supporting system.
//
// Parameters:
// statement - A statement that a macro such as EXPECT_DEATH would test
// for program termination. This macro has to make sure this
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter iff EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
// compile inside functions where ASSERT_DEATH doesn't
// compile.
//
// The branch that has an always false condition is used to ensure that
// statement and regex are compiled (and thus syntactically correct) but
// never executed. The unreachable code macro protects the terminator
// statement from generating an 'unreachable code' warning in case
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
#endif // GTEST_HAS_DEATH_TEST
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_

View file

@ -0,0 +1,206 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: keith.ray@gmail.com (Keith Ray)
//
// Google Test filepath utilities
//
// This header file declares classes and functions used internally by
// Google Test. They are subject to change without notice.
//
// This file is #included in <gtest/internal/gtest-internal.h>.
// Do not include this header file separately!
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include "gtest/internal/gtest-string.h"
namespace testing {
namespace internal {
// FilePath - a class for file and directory pathname manipulation which
// handles platform-specific conventions (like the pathname separator).
// Used for helper functions for naming files in a directory for xml output.
// Except for Set methods, all methods are const or static, which provides an
// "immutable value object" -- useful for peace of mind.
// A FilePath with a value ending in a path separator ("like/this/") represents
// a directory, otherwise it is assumed to represent a file. In either case,
// it may or may not represent an actual file or directory in the file system.
// Names are NOT checked for syntax correctness -- no checking for illegal
// characters, malformed paths, etc.
class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") { }
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
Normalize();
}
FilePath& operator=(const FilePath& rhs) {
Set(rhs);
return *this;
}
void Set(const FilePath& rhs) {
pathname_ = rhs.pathname_;
}
const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); }
// Returns the current working directory, or "" if unsuccessful.
static FilePath GetCurrentDir();
// Given directory = "dir", base_name = "test", number = 0,
// extension = "xml", returns "dir/test.xml". If number is greater
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
static FilePath MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const char* extension);
// Given directory = "dir", relative_path = "test.xml",
// returns "dir/test.xml".
// On Windows, uses \ as the separator rather than /.
static FilePath ConcatPaths(const FilePath& directory,
const FilePath& relative_path);
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
// directory/base_name_<number>.extension if directory/base_name.extension
// already exists. The number will be incremented until a pathname is found
// that does not already exist.
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
// There could be a race condition if two or more processes are calling this
// function at the same time -- they could both pick the same filename.
static FilePath GenerateUniqueFileName(const FilePath& directory,
const FilePath& base_name,
const char* extension);
// Returns true iff the path is "".
bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns
// the name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath RemoveTrailingPathSeparator() const;
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveDirectoryName() const;
// RemoveFileName returns the directory path with the filename removed.
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveFileName() const;
// Returns a copy of the FilePath with the case-insensitive extension removed.
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
// FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath.
FilePath RemoveExtension(const char* extension) const;
// Creates directories so that path exists. Returns true if successful or if
// the directories already exist; returns false if unable to create
// directories for any reason. Will also return false if the FilePath does
// not represent a directory (that is, it doesn't end with a path separator).
bool CreateDirectoriesRecursively() const;
// Create the directory so that path exists. Returns true if successful or
// if the directory already exists; returns false if unable to create the
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool CreateFolder() const;
// Returns true if FilePath describes something in the file-system,
// either a file, directory, or whatever, and that something exists.
bool FileOrDirectoryExists() const;
// Returns true if pathname describes a directory in the file-system
// that exists.
bool DirectoryExists() const;
// Returns true if FilePath ends with a path separator, which indicates that
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool IsDirectory() const;
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
bool IsRootDirectory() const;
// Returns true if pathname describes an absolute path.
bool IsAbsolutePath() const;
private:
// Replaces multiple consecutive separators with a single separator.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
//
// A pathname with multiple consecutive separators may occur either through
// user error or as a result of some scripts or APIs that generate a pathname
// with a trailing separator. On other platforms the same API or script
// may NOT generate a pathname with a trailing "/". Then elsewhere that
// pathname may have another "/" and pathname components added to it,
// without checking for the separator already being there.
// The script language and operating system may allow paths like "foo//bar"
// but some of the functions in FilePath will not handle that correctly. In
// particular, RemoveTrailingPathSeparator() only removes one separator, and
// it is called in CreateDirectoriesRecursively() assuming that it will change
// a pathname from directory syntax (trailing separator) to filename syntax.
//
// On Windows this method also replaces the alternate path separator '/' with
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
// "bar\\foo".
void Normalize();
// Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
std::string pathname_;
}; // class FilePath
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,233 @@
// Copyright 2003 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Dan Egnor (egnor@google.com)
//
// A "smart" pointer type with reference tracking. Every pointer to a
// particular object is kept on a circular linked list. When the last pointer
// to an object is destroyed or reassigned, the object is deleted.
//
// Used properly, this deletes the object when the last reference goes away.
// There are several caveats:
// - Like all reference counting schemes, cycles lead to leaks.
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
// - Every time a pointer is assigned, the entire list of pointers to that
// object is traversed. This class is therefore NOT SUITABLE when there
// will often be more than two or three pointers to a particular object.
// - References are only tracked as long as linked_ptr<> objects are copied.
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
// will happen (double deletion).
//
// A good use of this class is storing object references in STL containers.
// You can safely put linked_ptr<> in a vector<>.
// Other uses may not be as good.
//
// Note: If you use an incomplete type with linked_ptr<>, the class
// *containing* linked_ptr<> must have a constructor and destructor (even
// if they do nothing!).
//
// Bill Gibbons suggested we use something like this.
//
// Thread Safety:
// Unlike other linked_ptr implementations, in this implementation
// a linked_ptr object is thread-safe in the sense that:
// - it's safe to copy linked_ptr objects concurrently,
// - it's safe to copy *from* a linked_ptr and read its underlying
// raw pointer (e.g. via get()) concurrently, and
// - it's safe to write to two linked_ptrs that point to the same
// shared object concurrently.
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
// confusion with normal linked_ptr.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#include <stdlib.h>
#include <assert.h>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
// Protects copying of all linked_ptr objects.
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
// This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
// So, it needs to be possible for different types of linked_ptr to participate
// in the same circular linked list, so we need a single class type here.
//
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
class linked_ptr_internal {
public:
// Create a new circle that includes only this instance.
void join_new() {
next_ = this;
}
// Many linked_ptr operations may change p.link_ for some linked_ptr
// variable p in the same circle as this object. Therefore we need
// to prevent two such operations from occurring concurrently.
//
// Note that different types of linked_ptr objects can coexist in a
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
// linked_ptr<Derived2>). Therefore we must use a single mutex to
// protect all linked_ptr objects. This can create serious
// contention in production code, but is acceptable in a testing
// framework.
// Join an existing circle.
void join(linked_ptr_internal const* ptr)
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
linked_ptr_internal const* p = ptr;
while (p->next_ != ptr) p = p->next_;
p->next_ = this;
next_ = ptr;
}
// Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another.
bool depart()
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
if (next_ == this) return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this) p = p->next_;
p->next_ = next_;
return false;
}
private:
mutable linked_ptr_internal const* next_;
};
template <typename T>
class linked_ptr {
public:
typedef T element_type;
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
linked_ptr(linked_ptr const& ptr) { // NOLINT
assert(&ptr != this);
copy(&ptr);
}
// Assignment releases the old value and acquires the new.
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
depart();
copy(&ptr);
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr) {
if (&ptr != this) {
depart();
copy(&ptr);
}
return *this;
}
// Smart pointer members.
void reset(T* ptr = NULL) {
depart();
capture(ptr);
}
T* get() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
bool operator==(T* p) const { return value_ == p; }
bool operator!=(T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const {
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const {
return value_ != ptr.get();
}
private:
template <typename U>
friend class linked_ptr;
T* value_;
linked_ptr_internal link_;
void depart() {
if (link_.depart()) delete value_;
}
void capture(T* ptr) {
value_ = ptr;
link_.join_new();
}
template <typename U> void copy(linked_ptr<U> const* ptr) {
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
};
template<typename T> inline
bool operator==(T* ptr, const linked_ptr<T>& x) {
return ptr == x.get();
}
template<typename T> inline
bool operator!=(T* ptr, const linked_ptr<T>& x) {
return ptr != x.get();
}
// A function to convert T* into linked_ptr<T>
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,301 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently Google Test supports at most $n arguments in Values,
// and at most $maxtuple arguments in Combine. Please contact
// googletestframework@googlegroups.com if you need more.
// Please note that the number of arguments to Combine is limited
// by the maximum arity of the implementation of tr1::tuple which is
// currently set at $maxtuple.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_HAS_PARAM_TEST
namespace testing {
// Forward declarations of ValuesIn(), which is implemented in
// include/gtest/gtest-param-test.h.
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end);
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container);
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
template <typename T1>
class ValueArray1 {
public:
explicit ValueArray1(T1 v1) : v1_(v1) {}
template <typename T>
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
private:
// No implementation - assignment is unsupported.
void operator=(const ValueArray1& other);
const T1 v1_;
};
$range i 2..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
class ValueArray$i {
public:
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {$for j, [[static_cast<T>(v$(j)_)]]};
return ValuesIn(array);
}
private:
// No implementation - assignment is unsupported.
void operator=(const ValueArray$i& other);
$for j [[
const T$j v$(j)_;
]]
};
]]
# if GTEST_HAS_COMBINE
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Generates values from the Cartesian product of values produced
// by the argument generators.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
class CartesianProductGenerator$i
: public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {
public:
typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
virtual ~CartesianProductGenerator$i() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
const ParamGenerator<T$j>& g$j,
const typename ParamGenerator<T$j>::iterator& current$(j)]])
: base_(base),
$for j, [[
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
]] {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current$(i)_;
$for k [[
if (current$(i+2-k)_ == end$(i+2-k)_) {
current$(i+2-k)_ = begin$(i+2-k)_;
++current$(i+2-k-1)_;
}
]]
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
($for j && [[
current$(j)_ == typed_other->current$(j)_
]]);
}
private:
Iterator(const Iterator& other)
: base_(other.base_), $for j, [[
begin$(j)_(other.begin$(j)_),
end$(j)_(other.end$(j)_),
current$(j)_(other.current$(j)_)
]] {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType($for j, [[*current$(j)_]]);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
$for j || [[
current$(j)_ == end$(j)_
]];
}
// No implementation - assignment is unsupported.
void operator=(const Iterator& other);
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
$for j [[
const typename ParamGenerator<T$j>::iterator begin$(j)_;
const typename ParamGenerator<T$j>::iterator end$(j)_;
typename ParamGenerator<T$j>::iterator current$(j)_;
]]
ParamType current_value_;
}; // class CartesianProductGenerator$i::Iterator
// No implementation - assignment is unsupported.
void operator=(const CartesianProductGenerator$i& other);
$for j [[
const ParamGenerator<T$j> g$(j)_;
]]
}; // class CartesianProductGenerator$i
]]
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Helper classes providing Combine() with polymorphic features. They allow
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
// convertible to U.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[class Generator$j]]>
class CartesianProductHolder$i {
public:
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
template <$for j, [[typename T$j]]>
operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {
return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(
new CartesianProductGenerator$i<$for j, [[T$j]]>(
$for j,[[
static_cast<ParamGenerator<T$j> >(g$(j)_)
]]));
}
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder$i& other);
$for j [[
const Generator$j g$(j)_;
]]
}; // class CartesianProductHolder$i
]]
# endif // GTEST_HAS_COMBINE
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_

View file

@ -0,0 +1,619 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#include <iterator>
#include <utility>
#include <vector>
// scripts/fuse_gtest.py depends on gtest's own header being #included
// *unconditionally*. Therefore these #includes cannot be moved
// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-linked_ptr.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h"
#if GTEST_HAS_PARAM_TEST
namespace testing {
namespace internal {
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Outputs a message explaining invalid registration of different
// fixture class for the same test case. This may happen when
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
const char* file, int line);
template <typename> class ParamGeneratorInterface;
template <typename> class ParamGenerator;
// Interface for iterating over elements provided by an implementation
// of ParamGeneratorInterface<T>.
template <typename T>
class ParamIteratorInterface {
public:
virtual ~ParamIteratorInterface() {}
// A pointer to the base generator instance.
// Used only for the purposes of iterator comparison
// to make sure that two iterators belong to the same generator.
virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
// Advances iterator to point to the next element
// provided by the generator. The caller is responsible
// for not calling Advance() on an iterator equal to
// BaseGenerator()->End().
virtual void Advance() = 0;
// Clones the iterator object. Used for implementing copy semantics
// of ParamIterator<T>.
virtual ParamIteratorInterface* Clone() const = 0;
// Dereferences the current iterator and provides (read-only) access
// to the pointed value. It is the caller's responsibility not to call
// Current() on an iterator equal to BaseGenerator()->End().
// Used for implementing ParamGenerator<T>::operator*().
virtual const T* Current() const = 0;
// Determines whether the given iterator and other point to the same
// element in the sequence generated by the generator.
// Used for implementing ParamGenerator<T>::operator==().
virtual bool Equals(const ParamIteratorInterface& other) const = 0;
};
// Class iterating over elements provided by an implementation of
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
// and implements the const forward iterator concept.
template <typename T>
class ParamIterator {
public:
typedef T value_type;
typedef const T& reference;
typedef ptrdiff_t difference_type;
// ParamIterator assumes ownership of the impl_ pointer.
ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
ParamIterator& operator=(const ParamIterator& other) {
if (this != &other)
impl_.reset(other.impl_->Clone());
return *this;
}
const T& operator*() const { return *impl_->Current(); }
const T* operator->() const { return impl_->Current(); }
// Prefix version of operator++.
ParamIterator& operator++() {
impl_->Advance();
return *this;
}
// Postfix version of operator++.
ParamIterator operator++(int /*unused*/) {
ParamIteratorInterface<T>* clone = impl_->Clone();
impl_->Advance();
return ParamIterator(clone);
}
bool operator==(const ParamIterator& other) const {
return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
}
bool operator!=(const ParamIterator& other) const {
return !(*this == other);
}
private:
friend class ParamGenerator<T>;
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
scoped_ptr<ParamIteratorInterface<T> > impl_;
};
// ParamGeneratorInterface<T> is the binary interface to access generators
// defined in other translation units.
template <typename T>
class ParamGeneratorInterface {
public:
typedef T ParamType;
virtual ~ParamGeneratorInterface() {}
// Generator interface definition
virtual ParamIteratorInterface<T>* Begin() const = 0;
virtual ParamIteratorInterface<T>* End() const = 0;
};
// Wraps ParamGeneratorInterface<T> and provides general generator syntax
// compatible with the STL Container concept.
// This class implements copy initialization semantics and the contained
// ParamGeneratorInterface<T> instance is shared among all copies
// of the original object. This is possible because that instance is immutable.
template<typename T>
class ParamGenerator {
public:
typedef ParamIterator<T> iterator;
explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
ParamGenerator& operator=(const ParamGenerator& other) {
impl_ = other.impl_;
return *this;
}
iterator begin() const { return iterator(impl_->Begin()); }
iterator end() const { return iterator(impl_->End()); }
private:
linked_ptr<const ParamGeneratorInterface<T> > impl_;
};
// Generates values from a range of two comparable values. Can be used to
// generate sequences of user-defined types that implement operator+() and
// operator<().
// This class is used in the Range() function.
template <typename T, typename IncrementT>
class RangeGenerator : public ParamGeneratorInterface<T> {
public:
RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), end_(end),
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
virtual ~RangeGenerator() {}
virtual ParamIteratorInterface<T>* Begin() const {
return new Iterator(this, begin_, 0, step_);
}
virtual ParamIteratorInterface<T>* End() const {
return new Iterator(this, end_, end_index_, step_);
}
private:
class Iterator : public ParamIteratorInterface<T> {
public:
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
IncrementT step)
: base_(base), value_(value), index_(index), step_(step) {}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
return base_;
}
virtual void Advance() {
value_ = value_ + step_;
index_++;
}
virtual ParamIteratorInterface<T>* Clone() const {
return new Iterator(*this);
}
virtual const T* Current() const { return &value_; }
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const int other_index =
CheckedDowncastToActualType<const Iterator>(&other)->index_;
return index_ == other_index;
}
private:
Iterator(const Iterator& other)
: ParamIteratorInterface<T>(),
base_(other.base_), value_(other.value_), index_(other.index_),
step_(other.step_) {}
// No implementation - assignment is unsupported.
void operator=(const Iterator& other);
const ParamGeneratorInterface<T>* const base_;
T value_;
int index_;
const IncrementT step_;
}; // class RangeGenerator::Iterator
static int CalculateEndIndex(const T& begin,
const T& end,
const IncrementT& step) {
int end_index = 0;
for (T i = begin; i < end; i = i + step)
end_index++;
return end_index;
}
// No implementation - assignment is unsupported.
void operator=(const RangeGenerator& other);
const T begin_;
const T end_;
const IncrementT step_;
// The index for the end() iterator. All the elements in the generated
// sequence are indexed (0-based) to aid iterator comparison.
const int end_index_;
}; // class RangeGenerator
// Generates values from a pair of STL-style iterators. Used in the
// ValuesIn() function. The elements are copied from the source range
// since the source can be located on the stack, and the generator
// is likely to persist beyond that stack frame.
template <typename T>
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
public:
template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
: container_(begin, end) {}
virtual ~ValuesInIteratorRangeGenerator() {}
virtual ParamIteratorInterface<T>* Begin() const {
return new Iterator(this, container_.begin());
}
virtual ParamIteratorInterface<T>* End() const {
return new Iterator(this, container_.end());
}
private:
typedef typename ::std::vector<T> ContainerType;
class Iterator : public ParamIteratorInterface<T> {
public:
Iterator(const ParamGeneratorInterface<T>* base,
typename ContainerType::const_iterator iterator)
: base_(base), iterator_(iterator) {}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
return base_;
}
virtual void Advance() {
++iterator_;
value_.reset();
}
virtual ParamIteratorInterface<T>* Clone() const {
return new Iterator(*this);
}
// We need to use cached value referenced by iterator_ because *iterator_
// can return a temporary object (and of type other then T), so just
// having "return &*iterator_;" doesn't work.
// value_ is updated here and not in Advance() because Advance()
// can advance iterator_ beyond the end of the range, and we cannot
// detect that fact. The client code, on the other hand, is
// responsible for not calling Current() on an out-of-range iterator.
virtual const T* Current() const {
if (value_.get() == NULL)
value_.reset(new T(*iterator_));
return value_.get();
}
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
return iterator_ ==
CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
}
private:
Iterator(const Iterator& other)
// The explicit constructor call suppresses a false warning
// emitted by gcc when supplied with the -Wextra option.
: ParamIteratorInterface<T>(),
base_(other.base_),
iterator_(other.iterator_) {}
const ParamGeneratorInterface<T>* const base_;
typename ContainerType::const_iterator iterator_;
// A cached value of *iterator_. We keep it here to allow access by
// pointer in the wrapping iterator's operator->().
// value_ needs to be mutable to be accessed in Current().
// Use of scoped_ptr helps manage cached value's lifetime,
// which is bound by the lifespan of the iterator itself.
mutable scoped_ptr<const T> value_;
}; // class ValuesInIteratorRangeGenerator::Iterator
// No implementation - assignment is unsupported.
void operator=(const ValuesInIteratorRangeGenerator& other);
const ContainerType container_;
}; // class ValuesInIteratorRangeGenerator
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Stores a parameter value and later creates tests parameterized with that
// value.
template <class TestClass>
class ParameterizedTestFactory : public TestFactoryBase {
public:
typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) :
parameter_(parameter) {}
virtual Test* CreateTest() {
TestClass::SetParam(&parameter_);
return new TestClass();
}
private:
const ParamType parameter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// TestMetaFactoryBase is a base class for meta-factories that create
// test factories for passing into MakeAndRegisterTestInfo function.
template <class ParamType>
class TestMetaFactoryBase {
public:
virtual ~TestMetaFactoryBase() {}
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// TestMetaFactory creates test factories for passing into
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
// ownership of test factory pointer, same factory object cannot be passed
// into that method twice. But ParameterizedTestCaseInfo is going to call
// it for each Test/Parameter value combination. Thus it needs meta factory
// creator class.
template <class TestCase>
class TestMetaFactory
: public TestMetaFactoryBase<typename TestCase::ParamType> {
public:
typedef typename TestCase::ParamType ParamType;
TestMetaFactory() {}
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
return new ParameterizedTestFactory<TestCase>(parameter);
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseInfoBase is a generic interface
// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
// accumulates test information provided by TEST_P macro invocations
// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
// and uses that information to register all resulting test instances
// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
// a collection of pointers to the ParameterizedTestCaseInfo objects
// and calls RegisterTests() on each of them when asked.
class ParameterizedTestCaseInfoBase {
public:
virtual ~ParameterizedTestCaseInfoBase() {}
// Base part of test case name for display purposes.
virtual const string& GetTestCaseName() const = 0;
// Test case id to verify identity.
virtual TypeId GetTestCaseTypeId() const = 0;
// UnitTest class invokes this method to register tests in this
// test case right before running them in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single
// instance of a ParameterizedTestCaseInfoBase derived class.
virtual void RegisterTests() = 0;
protected:
ParameterizedTestCaseInfoBase() {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
// macro invocations for a particular test case and generators
// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
// test case. It registers tests with all values generated by all
// generators when asked.
template <class TestCase>
class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
public:
// ParamType and GeneratorCreationFunc are private types but are required
// for declarations of public methods AddTestPattern() and
// AddTestCaseInstantiation().
typedef typename TestCase::ParamType ParamType;
// A function that returns an instance of appropriate generator type.
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
explicit ParameterizedTestCaseInfo(const char* name)
: test_case_name_(name) {}
// Test case base name for display purposes.
virtual const string& GetTestCaseName() const { return test_case_name_; }
// Test case id to verify identity.
virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
// TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure.
// test_case_name is the base name of the test case (without invocation
// prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test case base name and DoBar is test base name.
void AddTestPattern(const char* test_case_name,
const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory) {
tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
test_base_name,
meta_factory)));
}
// INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
// about a generator.
int AddTestCaseInstantiation(const string& instantiation_name,
GeneratorCreationFunc* func,
const char* /* file */,
int /* line */) {
instantiations_.push_back(::std::make_pair(instantiation_name, func));
return 0; // Return value used only to run this method in namespace scope.
}
// UnitTest class invokes this method to register tests in this test case
// test cases right before running tests in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single
// instance of a ParameterizedTestCaseInfoBase derived class.
// UnitTest has a guard to prevent from calling this method more then once.
virtual void RegisterTests() {
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
linked_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin(); gen_it != instantiations_.end();
++gen_it) {
const string& instantiation_name = gen_it->first;
ParamGenerator<ParamType> generator((*gen_it->second)());
string test_case_name;
if ( !instantiation_name.empty() )
test_case_name = instantiation_name + "/";
test_case_name += test_info->test_case_base_name;
int i = 0;
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
Message test_name_stream;
test_name_stream << test_info->test_base_name << "/" << i;
MakeAndRegisterTestInfo(
test_case_name.c_str(),
test_name_stream.GetString().c_str(),
NULL, // No type parameter.
PrintToString(*param_it).c_str(),
GetTestCaseTypeId(),
TestCase::SetUpTestCase,
TestCase::TearDownTestCase,
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
} // for test_it
} // RegisterTests
private:
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
TestInfo(const char* a_test_case_base_name,
const char* a_test_base_name,
TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
test_case_base_name(a_test_case_base_name),
test_base_name(a_test_base_name),
test_meta_factory(a_test_meta_factory) {}
const string test_case_base_name;
const string test_base_name;
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
};
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
// Keeps pairs of <Instantiation name, Sequence generator creation function>
// received from INSTANTIATE_TEST_CASE_P macros.
typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> >
InstantiationContainer;
const string test_case_name_;
TestInfoContainer tests_;
InstantiationContainer instantiations_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
}; // class ParameterizedTestCaseInfo
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
// macros use it to locate their corresponding ParameterizedTestCaseInfo
// descriptors.
class ParameterizedTestCaseRegistry {
public:
ParameterizedTestCaseRegistry() {}
~ParameterizedTestCaseRegistry() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
delete *it;
}
}
// Looks up or creates and returns a structure containing information about
// tests and instantiations of a particular test case.
template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name,
const char* file,
int line) {
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
if ((*it)->GetTestCaseName() == test_case_name) {
if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test case setup and tear-down in this case.
ReportInvalidTestCaseType(test_case_name, file, line);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info = CheckedDowncastToActualType<
ParameterizedTestCaseInfo<TestCase> >(*it);
}
break;
}
}
if (typed_test_info == NULL) {
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
test_case_infos_.push_back(typed_test_info);
}
return typed_test_info;
}
void RegisterTests() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
(*it)->RegisterTests();
}
}
private:
typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
TestCaseInfoContainer test_case_infos_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
};
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,167 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file declares the String class and functions used internally by
// Google Test. They are subject to change without notice. They should not used
// by code external to Google Test.
//
// This header file is #included by <gtest/internal/gtest-internal.h>.
// It should not be #included by other files.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder.
# include <mem.h>
#endif
#include <string.h>
#include <string>
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
// String - an abstract class holding static string utilities.
class GTEST_API_ String {
public:
// Static utility methods
// Clones a 0-terminated C string, allocating memory using new. The
// caller is responsible for deleting the return value using
// delete[]. Returns the cloned string, or NULL if the input is
// NULL.
//
// This is different from strdup() in string.h, which allocates
// memory using malloc().
static const char* CloneCString(const char* c_str);
#if GTEST_OS_WINDOWS_MOBILE
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
// able to pass strings to Win32 APIs on CE we need to convert them
// to 'Unicode', UTF-16.
// Creates a UTF-16 wide string from the given ANSI string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the wide string, or NULL if the
// input is NULL.
//
// The wide string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static LPCWSTR AnsiToUtf16(const char* c_str);
// Creates an ANSI string from the given wide string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the ANSI string, or NULL if the
// input is NULL.
//
// The returned string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
#endif
// Compares two C strings. Returns true iff they have the same content.
//
// Unlike strcmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CStringEquals(const char* lhs, const char* rhs);
// Converts a wide C string to a String using the UTF-8 encoding.
// NULL will be converted to "(null)". If an error occurred during
// the conversion, "(failed to convert from wide string)" is
// returned.
static std::string ShowWideCString(const wchar_t* wide_c_str);
// Compares two wide C strings. Returns true iff they have the same
// content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
// Compares two C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
// including the empty string.
// NB: The implementations on different platforms slightly differ.
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
// environment variable. On GNU platform this method uses wcscasecmp
// which compares according to LC_CTYPE category of the current locale.
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
// current locale.
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
// Returns true iff the given string ends with the given suffix, ignoring
// case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
// Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value as "%X".
static std::string FormatHexInt(int value);
// Formats a byte as "%02X".
static std::string FormatByte(unsigned char value);
private:
String(); // Not meant to be instantiated.
}; // class String
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0".
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,339 @@
$$ -*- mode: c++; -*-
$var n = 10 $$ Maximum number of tuple fields we want to support.
$$ This meta comment fixes auto-indentation in Emacs. }}
// Copyright 2009 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
#include <utility> // For ::std::pair.
// The compiler used in Symbian has a bug that prevents us from declaring the
// tuple template as a friend (it complains that tuple is redefined). This
// hack bypasses the bug by declaring the members that should otherwise be
// private as public.
// Sun Studio versions < 12 also have the above bug.
#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
#else
# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
private:
#endif
$range i 0..n-1
$range j 0..n
$range k 1..n
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<>
$for k [[
$range m 0..k-1
$range m2 k..n-1
#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
]]
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
$for j [[
$range m 0..j-1
#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
]]
// In theory, defining stuff in the ::std namespace is undefined
// behavior. We can do this as we are playing the role of a standard
// library vendor.
namespace std {
namespace tr1 {
template <$for i, [[typename T$i = void]]>
class tuple;
// Anything in namespace gtest_internal is Google Test's INTERNAL
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
namespace gtest_internal {
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
template <typename T>
struct ByRef { typedef const T& type; }; // NOLINT
template <typename T>
struct ByRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for ByRef.
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
// is the same as tr1::add_reference<T>::type.
template <typename T>
struct AddRef { typedef T& type; }; // NOLINT
template <typename T>
struct AddRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for AddRef.
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
// A helper for implementing get<k>().
template <int k> class Get;
// A helper for implementing tuple_element<k, T>. kIndexValid is true
// iff k < the number of fields in tuple type T.
template <bool kIndexValid, int kIndex, class Tuple>
struct TupleElement;
$for i [[
template <GTEST_$(n)_TYPENAMES_(T)>
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T) > {
typedef T$i type;
};
]]
} // namespace gtest_internal
template <>
class tuple<> {
public:
tuple() {}
tuple(const tuple& /* t */) {}
tuple& operator=(const tuple& /* t */) { return *this; }
};
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public:
template <int k> friend class gtest_internal::Get;
tuple() : $for m, [[f$(m)_()]] {}
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
$for m, [[f$(m)_(f$m)]] {}
tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
template <GTEST_$(k)_TYPENAMES_(U)>
tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
$if k == 2 [[
template <typename U0, typename U1>
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
]]
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
return CopyFrom(t);
}
$if k == 2 [[
template <typename U0, typename U1>
tuple& operator=(const ::std::pair<U0, U1>& p) {
f0_ = p.first;
f1_ = p.second;
return *this;
}
]]
GTEST_DECLARE_TUPLE_AS_FRIEND_
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
$for m [[
f$(m)_ = t.f$(m)_;
]]
return *this;
}
$for m [[
T$m f$(m)_;
]]
};
]]
// 6.1.3.2 Tuple creation functions.
// Known limitations: we don't support passing an
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
// implement tie().
inline tuple<> make_tuple() { return tuple<>(); }
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
}
]]
// 6.1.3.3 Tuple helper classes.
template <typename Tuple> struct tuple_size;
$for j [[
template <GTEST_$(j)_TYPENAMES_(T)>
struct tuple_size<GTEST_$(j)_TUPLE_(T) > {
static const int value = $j;
};
]]
template <int k, class Tuple>
struct tuple_element {
typedef typename gtest_internal::TupleElement<
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
};
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
// 6.1.3.4 Element access.
namespace gtest_internal {
$for i [[
template <>
class Get<$i> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
Field(Tuple& t) { return t.f$(i)_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
ConstField(const Tuple& t) { return t.f$(i)_; }
};
]]
} // namespace gtest_internal
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::Field(t);
}
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(const GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::ConstField(t);
}
// 6.1.3.5 Relational operators
// We only implement == and !=, as we don't have a need for the rest yet.
namespace gtest_internal {
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
// first k fields of t1 equals the first k fields of t2.
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
// k1 != k2.
template <int kSize1, int kSize2>
struct SameSizeTuplePrefixComparator;
template <>
struct SameSizeTuplePrefixComparator<0, 0> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
return true;
}
};
template <int k>
struct SameSizeTuplePrefixComparator<k, k> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
}
};
} // namespace gtest_internal
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) {
return gtest_internal::SameSizeTuplePrefixComparator<
tuple_size<GTEST_$(n)_TUPLE_(T) >::value,
tuple_size<GTEST_$(n)_TUPLE_(U) >::value>::Eq(t, u);
}
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
// 6.1.4 Pairs.
// Unimplemented.
} // namespace tr1
} // namespace std
$for j [[
#undef GTEST_$(j)_TUPLE_
]]
$for j [[
#undef GTEST_$(j)_TYPENAMES_
]]
#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
#undef GTEST_BY_REF_
#undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,297 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of type lists we want to support.
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Type utilities needed for implementing typed and type-parameterized
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently we support at most $n types in a list, and at most $n
// type-parameterized tests in one type-parameterized test case.
// Please contact googletestframework@googlegroups.com if you need
// more.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include "gtest/internal/gtest-port.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
# if GTEST_HAS_CXXABI_H_
# include <cxxabi.h>
# elif defined(__HP_aCC)
# include <acxx_demangle.h>
# endif // GTEST_HASH_CXXABI_H_
namespace testing {
namespace internal {
// GetTypeName<T>() returns a human-readable name of type T.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
template <typename T>
std::string GetTypeName() {
# if GTEST_HAS_RTTI
const char* const name = typeid(T).name();
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it.
# if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle;
# endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, 0, 0, &status);
const std::string name_str(status == 0 ? readable_name : name);
free(readable_name);
return name_str;
# else
return name;
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
# else
return "<type>";
# endif // GTEST_HAS_RTTI
}
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
// type. This can be used as a compile-time assertion to ensure that
// two types are equal.
template <typename T1, typename T2>
struct AssertTypeEq;
template <typename T>
struct AssertTypeEq<T, T> {
typedef bool type;
};
// A unique type used as the default value for the arguments of class
// template Types. This allows us to simulate variadic templates
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
// support directly.
struct None {};
// The following family of struct and struct templates are used to
// represent type lists. In particular, TypesN<T1, T2, ..., TN>
// represents a type list with N types (T1, T2, ..., and TN) in it.
// Except for Types0, every struct in the family has two member types:
// Head for the first type in the list, and Tail for the rest of the
// list.
// The empty type list.
struct Types0 {};
// Type lists of length 1, 2, 3, and so on.
template <typename T1>
struct Types1 {
typedef T1 Head;
typedef Types0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
struct Types$i {
typedef T1 Head;
typedef Types$(i-1)<$for k, [[T$k]]> Tail;
};
]]
} // namespace internal
// We don't want to require the users to write TypesN<...> directly,
// as that would require them to count the length. Types<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Types<int>
// will appear as Types<int, None, None, ..., None> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Types<T1, ..., TN>, and Google Test will translate
// that to TypesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Types template.
$range i 1..n
template <$for i, [[typename T$i = internal::None]]>
struct Types {
typedef internal::Types$n<$for i, [[T$i]]> type;
};
template <>
struct Types<$for i, [[internal::None]]> {
typedef internal::Types0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[typename T$j]]>
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
typedef internal::Types$i<$for j, [[T$j]]> type;
};
]]
namespace internal {
# define GTEST_TEMPLATE_ template <typename T> class
// The template "selector" struct TemplateSel<Tmpl> is used to
// represent Tmpl, which must be a class template with one type
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined
// as the type Tmpl<T>. This allows us to actually instantiate the
// template "selected" by TemplateSel<Tmpl>.
//
// This trick is necessary for simulating typedef for class templates,
// which C++ doesn't support directly.
template <GTEST_TEMPLATE_ Tmpl>
struct TemplateSel {
template <typename T>
struct Bind {
typedef Tmpl<T> type;
};
};
# define GTEST_BIND_(TmplSel, T) \
TmplSel::template Bind<T>::type
// A unique struct template used as the default value for the
// arguments of class template Templates. This allows us to simulate
// variadic templates (e.g. Templates<int>, Templates<int, double>,
// and etc), which C++ doesn't support directly.
template <typename T>
struct NoneT {};
// The following family of struct and struct templates are used to
// represent template lists. In particular, TemplatesN<T1, T2, ...,
// TN> represents a list of N templates (T1, T2, ..., and TN). Except
// for Templates0, every struct in the family has two member types:
// Head for the selector of the first template in the list, and Tail
// for the rest of the list.
// The empty template list.
struct Templates0 {};
// Template lists of length 1, 2, 3, and so on.
template <GTEST_TEMPLATE_ T1>
struct Templates1 {
typedef TemplateSel<T1> Head;
typedef Templates0 Tail;
};
$range i 2..n
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates$i {
typedef TemplateSel<T1> Head;
typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
};
]]
// We don't want to require the users to write TemplatesN<...> directly,
// as that would require them to count the length. Templates<...> is much
// easier to write, but generates horrible messages when there is a
// compiler error, as gcc insists on printing out each template
// argument, even if it has the default value (this means Templates<list>
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
// errors).
//
// Our solution is to combine the best part of the two approaches: a
// user would write Templates<T1, ..., TN>, and Google Test will translate
// that to TemplatesN<T1, ..., TN> internally to make error messages
// readable. The translation is done by the 'type' member of the
// Templates template.
$range i 1..n
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
struct Templates {
typedef Templates$n<$for i, [[T$i]]> type;
};
template <>
struct Templates<$for i, [[NoneT]]> {
typedef Templates0 type;
};
$range i 1..n-1
$for i [[
$range j 1..i
$range k i+1..n
template <$for j, [[GTEST_TEMPLATE_ T$j]]>
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
typedef Templates$i<$for j, [[T$j]]> type;
};
]]
// The TypeList template makes it possible to use either a single type
// or a Types<...> list in TYPED_TEST_CASE() and
// INSTANTIATE_TYPED_TEST_CASE_P().
template <typename T>
struct TypeList {
typedef Types1<T> type;
};
$range i 1..n
template <$for i, [[typename T$i]]>
struct TypeList<Types<$for i, [[T$i]]> > {
typedef typename Types<$for i, [[T$i]]>::type type;
};
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_

View file

@ -0,0 +1,363 @@
# This was retrieved from
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
# See also (perhaps for new versions?)
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
#
# We've rewritten the inconsistency check code (from avahi), to work
# more broadly. In particular, it no longer assumes ld accepts -zdefs.
# This caused a restructing of the code, but the functionality has only
# changed a little.
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl @summary figure out how to build C programs using POSIX threads
dnl
dnl This macro figures out how to build C programs using POSIX threads.
dnl It sets the PTHREAD_LIBS output variable to the threads library and
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
dnl C compiler flags that are needed. (The user can also force certain
dnl compiler flags/libs to be tested by setting these environment
dnl variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl NOTE: You are assumed to not only compile your program with these
dnl flags, but also link it with them as well. e.g. you should link
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
dnl $LIBS
dnl
dnl If you are only building threads programs, you may wish to use
dnl these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
dnl default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform, or
dnl if you have any other suggestions or comments. This macro was based
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
dnl We are also grateful for the helpful feedback of numerous users.
dnl
dnl @category InstalledPackages
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
dnl @version 2006-05-29
dnl @license GPLWithACException
dnl
dnl Checks for GCC shared/pthread inconsistency based on work by
dnl Marcin Owsiany <marcin@owsiany.pl>
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
[attr_name=$attr; break])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
# The next part tries to detect GCC inconsistency with -shared on some
# architectures and systems. The problem is that in certain
# configurations, when -shared is specified, GCC "forgets" to
# internally use various flags which are still necessary.
#
# Prepare the flags
#
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
save_CC="$CC"
# Try with the flags determined by the earlier checks.
#
# -Wl,-z,defs forces link-time symbol resolution, so that the
# linking checks with -shared actually have any value
#
# FIXME: -fPIC is required for -shared on many architectures,
# so we specify it here, but the right way would probably be to
# properly detect whether it is actually required.
CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CC="$PTHREAD_CC"
# In order not to create several levels of indentation, we test
# the value of "$done" until we find the cure or run out of ideas.
done="no"
# First, make sure the CFLAGS we added are actually accepted by our
# compiler. If not (and OS X's ld, for instance, does not accept -z),
# then we can't do this test.
if test x"$done" = xno; then
AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
AC_TRY_LINK(,, , [done=yes])
if test "x$done" = xyes ; then
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([yes])
fi
fi
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fi
#
# Linux gcc on some architectures such as mips/mipsel forgets
# about -lpthread
#
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -lpthread fixes that])
LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
else
AC_MSG_RESULT([no])
fi
fi
#
# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
#
if test x"$done" = xno; then
AC_MSG_CHECKING([whether -lc_r fixes that])
LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[done=yes])
if test "x$done" = xyes; then
AC_MSG_RESULT([yes])
PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
else
AC_MSG_RESULT([no])
fi
fi
if test x"$done" = xno; then
# OK, we have run out of ideas
AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
# so it's not safe to assume that we may use pthreads
acx_pthread_ok=no
fi
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
CC="$save_CC"
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD

View file

@ -0,0 +1,74 @@
dnl GTEST_LIB_CHECK([minimum version [,
dnl action if found [,action if not found]]])
dnl
dnl Check for the presence of the Google Test library, optionally at a minimum
dnl version, and indicate a viable version with the HAVE_GTEST flag. It defines
dnl standard variables for substitution including GTEST_CPPFLAGS,
dnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines
dnl GTEST_VERSION as the version of Google Test found. Finally, it provides
dnl optional custom action slots in the event GTEST is found or not.
AC_DEFUN([GTEST_LIB_CHECK],
[
dnl Provide a flag to enable or disable Google Test usage.
AC_ARG_ENABLE([gtest],
[AS_HELP_STRING([--enable-gtest],
[Enable tests using the Google C++ Testing Framework.
(Default is enabled.)])],
[],
[enable_gtest=])
AC_ARG_VAR([GTEST_CONFIG],
[The exact path of Google Test's 'gtest-config' script.])
AC_ARG_VAR([GTEST_CPPFLAGS],
[C-like preprocessor flags for Google Test.])
AC_ARG_VAR([GTEST_CXXFLAGS],
[C++ compile flags for Google Test.])
AC_ARG_VAR([GTEST_LDFLAGS],
[Linker path and option flags for Google Test.])
AC_ARG_VAR([GTEST_LIBS],
[Library linking flags for Google Test.])
AC_ARG_VAR([GTEST_VERSION],
[The version of Google Test available.])
HAVE_GTEST="no"
AS_IF([test "x${enable_gtest}" != "xno"],
[AC_MSG_CHECKING([for 'gtest-config'])
AS_IF([test "x${enable_gtest}" != "xyes"],
[AS_IF([test -x "${enable_gtest}/scripts/gtest-config"],
[GTEST_CONFIG="${enable_gtest}/scripts/gtest-config"],
[GTEST_CONFIG="${enable_gtest}/bin/gtest-config"])
AS_IF([test -x "${GTEST_CONFIG}"], [],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([dnl
Unable to locate either a built or installed Google Test.
The specific location '${enable_gtest}' was provided for a built or installed
Google Test, but no 'gtest-config' script could be found at this location.])
])],
[AC_PATH_PROG([GTEST_CONFIG], [gtest-config])])
AS_IF([test -x "${GTEST_CONFIG}"],
[AC_MSG_RESULT([${GTEST_CONFIG}])
m4_ifval([$1],
[_gtest_min_version="--min-version=$1"
AC_MSG_CHECKING([for Google Test at least version >= $1])],
[_gtest_min_version="--min-version=0"
AC_MSG_CHECKING([for Google Test])])
AS_IF([${GTEST_CONFIG} ${_gtest_min_version}],
[AC_MSG_RESULT([yes])
HAVE_GTEST='yes'],
[AC_MSG_RESULT([no])])],
[AC_MSG_RESULT([no])])
AS_IF([test "x${HAVE_GTEST}" = "xyes"],
[GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`
GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`
GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
GTEST_LIBS=`${GTEST_CONFIG} --libs`
GTEST_VERSION=`${GTEST_CONFIG} --version`
AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])],
[AS_IF([test "x${enable_gtest}" = "xyes"],
[AC_MSG_ERROR([dnl
Google Test was enabled, but no viable version could be found.])
])])])
AC_SUBST([HAVE_GTEST])
AM_CONDITIONAL([HAVE_GTEST],[test "x$HAVE_GTEST" = "xyes"])
AS_IF([test "x$HAVE_GTEST" = "xyes"],
[m4_ifval([$2], [$2])],
[m4_ifval([$3], [$3])])
])

View file

@ -0,0 +1,82 @@
# A sample Makefile for building Google Test and using it in user
# tests. Please tweak it to suit your environment and project. You
# may want to move it to your project's root directory.
#
# SYNOPSIS:
#
# make [all] - makes everything.
# make TARGET - makes the given target.
# make clean - removes all files generated by make.
# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn't modify.
# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file.
GTEST_DIR = ..
# Where to find user code.
USER_DIR = ../samples
# Flags passed to the preprocessor.
# Set Google Test's header directory as a system directory, such that
# the compiler doesn't generate warnings in Google Test headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include
# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -pthread
# All tests produced by this Makefile. Remember to add new tests you
# created to the list.
TESTS = sample1_unittest
# All Google Test headers. Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
$(GTEST_DIR)/include/gtest/internal/*.h
# House-keeping build targets.
all : $(TESTS)
clean :
rm -f $(TESTS) gtest.a gtest_main.a *.o
# Builds gtest.a and gtest_main.a.
# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized. This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
gtest-all.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest-all.cc
gtest_main.o : $(GTEST_SRCS_)
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
$(GTEST_DIR)/src/gtest_main.cc
gtest.a : gtest-all.o
$(AR) $(ARFLAGS) $@ $^
gtest_main.a : gtest-all.o gtest_main.o
$(AR) $(ARFLAGS) $@ $^
# Builds a sample test. A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.
sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc
sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
$(USER_DIR)/sample1.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc
sample1_unittest : sample1.o sample1_unittest.o gtest_main.a
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

View file

@ -0,0 +1,45 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg = Debug|Win32
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0 = Debug|Win32
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg = Release|Win32
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.Build.0 = Release|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.ActiveCfg = Debug|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.Build.0 = Debug|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.ActiveCfg = Release|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.Build.0 = Release|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.ActiveCfg = Debug|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.Build.0 = Debug|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.ActiveCfg = Release|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.Build.0 = Release|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.ActiveCfg = Debug|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.Build.0 = Debug|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg = Release|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest-md"
ProjectGUID="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/gtestd.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/gtest.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\src\gtest-all.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,45 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_unittest.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.ActiveCfg = Debug|Win32
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.Build.0 = Debug|Win32
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.ActiveCfg = Release|Win32
{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.Build.0 = Release|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.ActiveCfg = Debug|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.Build.0 = Debug|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.ActiveCfg = Release|Win32
{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.Build.0 = Release|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.ActiveCfg = Debug|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0 = Debug|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg = Release|Win32
{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0 = Release|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg = Debug|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0 = Debug|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg = Release|Win32
{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest"
ProjectGUID="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/gtestd.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/gtest.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\src\gtest-all.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest_main-md"
ProjectGUID="{3AF54C8A-10BF-4332-9147-F68ED9862033}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/$(ProjectName)d.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/$(ProjectName).lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
<ProjectReference
ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"
Name="gtest-md"/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\src\gtest_main.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest_main"
ProjectGUID="{3AF54C8A-10BF-4332-9147-F68ED9862032}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/$(ProjectName)d.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="4"
CharacterSet="2"
ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/$(ProjectName).lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
<ProjectReference
ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
Name="gtest"/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\src\gtest_main.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest_prod_test-md"
ProjectGUID="{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_prod_test.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/gtest_prod_test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_prod_test.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
<ProjectReference
ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862033}"
Name="gtest_main-md"/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\test\gtest_prod_test.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\test\production.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\test\production.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest_prod_test"
ProjectGUID="{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_prod_test.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/gtest_prod_test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_prod_test.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
<ProjectReference
ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862032}"
Name="gtest_main"/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\test\gtest_prod_test.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\test\production.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\test\production.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest_unittest-md"
ProjectGUID="{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_unittest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/gtest_unittest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_unittest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
<ProjectReference
ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862033}"
Name="gtest_main-md"/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\test\gtest_unittest.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="1"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
BasicRuntimeChecks="0"
UsePrecompiledHeader="0"
DebugInformationFormat="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="gtest_unittest"
ProjectGUID="{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_unittest.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/gtest_unittest.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionName)/$(ConfigurationName)"
IntermediateDirectory="$(OutDir)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="3"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/gtest_unittest.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
<ProjectReference
ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862032}"
Name="gtest_main"/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\test\gtest_unittest.cc">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="1"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
BasicRuntimeChecks="0"
UsePrecompiledHeader="0"
DebugInformationFormat="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"
UsePrecompiledHeader="0"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,123 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Author: vladl@google.com (Vlad Losev)
// This provides interface PrimeTable that determines whether a number is a
// prime and determines a next prime number. This interface is used
// in Google Test samples demonstrating use of parameterized tests.
#ifndef GTEST_SAMPLES_PRIME_TABLES_H_
#define GTEST_SAMPLES_PRIME_TABLES_H_
#include <algorithm>
// The prime table interface.
class PrimeTable {
public:
virtual ~PrimeTable() {}
// Returns true iff n is a prime number.
virtual bool IsPrime(int n) const = 0;
// Returns the smallest prime number greater than p; or returns -1
// if the next prime is beyond the capacity of the table.
virtual int GetNextPrime(int p) const = 0;
};
// Implementation #1 calculates the primes on-the-fly.
class OnTheFlyPrimeTable : public PrimeTable {
public:
virtual bool IsPrime(int n) const {
if (n <= 1) return false;
for (int i = 2; i*i <= n; i++) {
// n is divisible by an integer other than 1 and itself.
if ((n % i) == 0) return false;
}
return true;
}
virtual int GetNextPrime(int p) const {
for (int n = p + 1; n > 0; n++) {
if (IsPrime(n)) return n;
}
return -1;
}
};
// Implementation #2 pre-calculates the primes and stores the result
// in an array.
class PreCalculatedPrimeTable : public PrimeTable {
public:
// 'max' specifies the maximum number the prime table holds.
explicit PreCalculatedPrimeTable(int max)
: is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {
CalculatePrimesUpTo(max);
}
virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; }
virtual bool IsPrime(int n) const {
return 0 <= n && n < is_prime_size_ && is_prime_[n];
}
virtual int GetNextPrime(int p) const {
for (int n = p + 1; n < is_prime_size_; n++) {
if (is_prime_[n]) return n;
}
return -1;
}
private:
void CalculatePrimesUpTo(int max) {
::std::fill(is_prime_, is_prime_ + is_prime_size_, true);
is_prime_[0] = is_prime_[1] = false;
for (int i = 2; i <= max; i++) {
if (!is_prime_[i]) continue;
// Marks all multiples of i (except i itself) as non-prime.
for (int j = 2*i; j <= max; j += i) {
is_prime_[j] = false;
}
}
}
const int is_prime_size_;
bool* const is_prime_;
// Disables compiler warning "assignment operator could not be generated."
void operator=(const PreCalculatedPrimeTable& rhs);
};
#endif // GTEST_SAMPLES_PRIME_TABLES_H_

View file

@ -0,0 +1,68 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#include "sample1.h"
// Returns n! (the factorial of n). For negative n, n! is defined to be 1.
int Factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
// Returns true iff n is a prime number.
bool IsPrime(int n) {
// Trivial case 1: small numbers
if (n <= 1) return false;
// Trivial case 2: even numbers
if (n % 2 == 0) return n == 2;
// Now, we have that n is odd and n >= 3.
// Try to divide n by every odd number i, starting from 3
for (int i = 3; ; i += 2) {
// We only have to try i up to the squre root of n
if (i > n/i) break;
// Now, we have i <= n/i < n.
// If n is divisible by i, n is not prime.
if (n % i == 0) return false;
}
// n has no integer factor in the range (1, n), and thus is prime.
return true;
}

View file

@ -0,0 +1,43 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE1_H_
#define GTEST_SAMPLES_SAMPLE1_H_
// Returns n! (the factorial of n). For negative n, n! is defined to be 1.
int Factorial(int n);
// Returns true iff n is a prime number.
bool IsPrime(int n);
#endif // GTEST_SAMPLES_SAMPLE1_H_

View file

@ -0,0 +1,144 @@
// Copyright 2009 Google Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to use Google Test listener API to implement
// a primitive leak checker.
#include <stdio.h>
#include <stdlib.h>
#include "gtest/gtest.h"
using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners;
using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;
namespace {
// We will track memory used by this class.
class Water {
public:
// Normal Water declarations go here.
// operator new and operator delete help us control water allocation.
void* operator new(size_t allocation_size) {
allocated_++;
return malloc(allocation_size);
}
void operator delete(void* block, size_t /* allocation_size */) {
allocated_--;
free(block);
}
static int allocated() { return allocated_; }
private:
static int allocated_;
};
int Water::allocated_ = 0;
// This event listener monitors how many Water objects are created and
// destroyed by each test, and reports a failure if a test leaks some Water
// objects. It does this by comparing the number of live Water objects at
// the beginning of a test and at the end of a test.
class LeakChecker : public EmptyTestEventListener {
private:
// Called before a test starts.
virtual void OnTestStart(const TestInfo& /* test_info */) {
initially_allocated_ = Water::allocated();
}
// Called after a test ends.
virtual void OnTestEnd(const TestInfo& /* test_info */) {
int difference = Water::allocated() - initially_allocated_;
// You can generate a failure in any event handler except
// OnTestPartResult. Just use an appropriate Google Test assertion to do
// it.
EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
}
int initially_allocated_;
};
TEST(ListenersTest, DoesNotLeak) {
Water* water = new Water;
delete water;
}
// This should fail when the --check_for_leaks command line flag is
// specified.
TEST(ListenersTest, LeaksWater) {
Water* water = new Water;
EXPECT_TRUE(water != NULL);
}
} // namespace
int main(int argc, char **argv) {
InitGoogleTest(&argc, argv);
bool check_for_leaks = false;
if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 )
check_for_leaks = true;
else
printf("%s\n", "Run this program with --check_for_leaks to enable "
"custom leak checking in the tests.");
// If we are given the --check_for_leaks command line flag, installs the
// leak checker.
if (check_for_leaks) {
TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
// Adds the leak checker to the end of the test event listener list,
// after the default text output printer and the default XML report
// generator.
//
// The order is important - it ensures that failures generated in the
// leak checker's OnTestEnd() method are processed by the text and XML
// printers *before* their OnTestEnd() methods are called, such that
// they are attributed to the right test. Remember that a listener
// receives an OnXyzStart event *after* listeners preceding it in the
// list received that event, and receives an OnXyzEnd event *before*
// listeners preceding it.
//
// We don't need to worry about deleting the new listener later, as
// Google Test will do it.
listeners.Append(new LeakChecker);
}
return RUN_ALL_TESTS();
}

View file

@ -0,0 +1,153 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to write a simple unit test for a function,
// using Google C++ testing framework.
//
// Writing a unit test using Google C++ testing framework is easy as 1-2-3:
// Step 1. Include necessary header files such that the stuff your
// test logic needs is declared.
//
// Don't forget gtest.h, which declares the testing framework.
#include <limits.h>
#include "sample1.h"
#include "gtest/gtest.h"
// Step 2. Use the TEST macro to define your tests.
//
// TEST has two parameters: the test case name and the test name.
// After using the macro, you should define your test logic between a
// pair of braces. You can use a bunch of macros to indicate the
// success or failure of a test. EXPECT_TRUE and EXPECT_EQ are
// examples of such macros. For a complete list, see gtest.h.
//
// <TechnicalDetails>
//
// In Google Test, tests are grouped into test cases. This is how we
// keep test code organized. You should put logically related tests
// into the same test case.
//
// The test case name and the test name should both be valid C++
// identifiers. And you should not use underscore (_) in the names.
//
// Google Test guarantees that each test you define is run exactly
// once, but it makes no guarantee on the order the tests are
// executed. Therefore, you should write your tests in such a way
// that their results don't depend on their order.
//
// </TechnicalDetails>
// Tests Factorial().
// Tests factorial of negative numbers.
TEST(FactorialTest, Negative) {
// This test is named "Negative", and belongs to the "FactorialTest"
// test case.
EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1));
EXPECT_GT(Factorial(-10), 0);
// <TechnicalDetails>
//
// EXPECT_EQ(expected, actual) is the same as
//
// EXPECT_TRUE((expected) == (actual))
//
// except that it will print both the expected value and the actual
// value when the assertion fails. This is very helpful for
// debugging. Therefore in this case EXPECT_EQ is preferred.
//
// On the other hand, EXPECT_TRUE accepts any Boolean expression,
// and is thus more general.
//
// </TechnicalDetails>
}
// Tests factorial of 0.
TEST(FactorialTest, Zero) {
EXPECT_EQ(1, Factorial(0));
}
// Tests factorial of positive numbers.
TEST(FactorialTest, Positive) {
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
// Tests IsPrime()
// Tests negative input.
TEST(IsPrimeTest, Negative) {
// This test belongs to the IsPrimeTest test case.
EXPECT_FALSE(IsPrime(-1));
EXPECT_FALSE(IsPrime(-2));
EXPECT_FALSE(IsPrime(INT_MIN));
}
// Tests some trivial cases.
TEST(IsPrimeTest, Trivial) {
EXPECT_FALSE(IsPrime(0));
EXPECT_FALSE(IsPrime(1));
EXPECT_TRUE(IsPrime(2));
EXPECT_TRUE(IsPrime(3));
}
// Tests positive input.
TEST(IsPrimeTest, Positive) {
EXPECT_FALSE(IsPrime(4));
EXPECT_TRUE(IsPrime(5));
EXPECT_FALSE(IsPrime(6));
EXPECT_TRUE(IsPrime(23));
}
// Step 3. Call RUN_ALL_TESTS() in main().
//
// We do this by linking in src/gtest_main.cc file, which consists of
// a main() function which calls RUN_ALL_TESTS() for us.
//
// This runs all the tests you've defined, prints the result, and
// returns 0 if successful, or 1 otherwise.
//
// Did you notice that we didn't register the tests? The
// RUN_ALL_TESTS() macro magically knows about all the tests we
// defined. Isn't this convenient?

View file

@ -0,0 +1,56 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#include "sample2.h"
#include <string.h>
// Clones a 0-terminated C string, allocating memory using new.
const char* MyString::CloneCString(const char* a_c_string) {
if (a_c_string == NULL) return NULL;
const size_t len = strlen(a_c_string);
char* const clone = new char[ len + 1 ];
memcpy(clone, a_c_string, len + 1);
return clone;
}
// Sets the 0-terminated C string this MyString object
// represents.
void MyString::Set(const char* a_c_string) {
// Makes sure this works when c_string == c_string_
const char* const temp = MyString::CloneCString(a_c_string);
delete[] c_string_;
c_string_ = temp;
}

View file

@ -0,0 +1,85 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE2_H_
#define GTEST_SAMPLES_SAMPLE2_H_
#include <string.h>
// A simple string class.
class MyString {
private:
const char* c_string_;
const MyString& operator=(const MyString& rhs);
public:
// Clones a 0-terminated C string, allocating memory using new.
static const char* CloneCString(const char* a_c_string);
////////////////////////////////////////////////////////////
//
// C'tors
// The default c'tor constructs a NULL string.
MyString() : c_string_(NULL) {}
// Constructs a MyString by cloning a 0-terminated C string.
explicit MyString(const char* a_c_string) : c_string_(NULL) {
Set(a_c_string);
}
// Copy c'tor
MyString(const MyString& string) : c_string_(NULL) {
Set(string.c_string_);
}
////////////////////////////////////////////////////////////
//
// D'tor. MyString is intended to be a final class, so the d'tor
// doesn't need to be virtual.
~MyString() { delete[] c_string_; }
// Gets the 0-terminated C string this MyString object represents.
const char* c_string() const { return c_string_; }
size_t Length() const {
return c_string_ == NULL ? 0 : strlen(c_string_);
}
// Sets the 0-terminated C string this MyString object represents.
void Set(const char* c_string);
};
#endif // GTEST_SAMPLES_SAMPLE2_H_

View file

@ -0,0 +1,109 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to write a more complex unit test for a class
// that has multiple member functions.
//
// Usually, it's a good idea to have one test for each method in your
// class. You don't have to do that exactly, but it helps to keep
// your tests organized. You may also throw in additional tests as
// needed.
#include "sample2.h"
#include "gtest/gtest.h"
// In this example, we test the MyString class (a simple string).
// Tests the default c'tor.
TEST(MyString, DefaultConstructor) {
const MyString s;
// Asserts that s.c_string() returns NULL.
//
// <TechnicalDetails>
//
// If we write NULL instead of
//
// static_cast<const char *>(NULL)
//
// in this assertion, it will generate a warning on gcc 3.4. The
// reason is that EXPECT_EQ needs to know the types of its
// arguments in order to print them when it fails. Since NULL is
// #defined as 0, the compiler will use the formatter function for
// int to print it. However, gcc thinks that NULL should be used as
// a pointer, not an int, and therefore complains.
//
// The root of the problem is C++'s lack of distinction between the
// integer number 0 and the null pointer constant. Unfortunately,
// we have to live with this fact.
//
// </TechnicalDetails>
EXPECT_STREQ(NULL, s.c_string());
EXPECT_EQ(0u, s.Length());
}
const char kHelloString[] = "Hello, world!";
// Tests the c'tor that accepts a C string.
TEST(MyString, ConstructorFromCString) {
const MyString s(kHelloString);
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1,
s.Length());
}
// Tests the copy c'tor.
TEST(MyString, CopyConstructor) {
const MyString s1(kHelloString);
const MyString s2 = s1;
EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString));
}
// Tests the Set method.
TEST(MyString, Set) {
MyString s;
s.Set(kHelloString);
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Set should work when the input pointer is the same as the one
// already in the MyString object.
s.Set(s.c_string());
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Can we set the MyString to NULL?
s.Set(NULL);
EXPECT_STREQ(NULL, s.c_string());
}

View file

@ -0,0 +1,172 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_
#define GTEST_SAMPLES_SAMPLE3_INL_H_
#include <stddef.h>
// Queue is a simple queue implemented as a singled-linked list.
//
// The element type must support copy constructor.
template <typename E> // E is the element type
class Queue;
// QueueNode is a node in a Queue, which consists of an element of
// type E and a pointer to the next node.
template <typename E> // E is the element type
class QueueNode {
friend class Queue<E>;
public:
// Gets the element in this node.
const E& element() const { return element_; }
// Gets the next node in the queue.
QueueNode* next() { return next_; }
const QueueNode* next() const { return next_; }
private:
// Creates a node with a given element value. The next pointer is
// set to NULL.
explicit QueueNode(const E& an_element) : element_(an_element), next_(NULL) {}
// We disable the default assignment operator and copy c'tor.
const QueueNode& operator = (const QueueNode&);
QueueNode(const QueueNode&);
E element_;
QueueNode* next_;
};
template <typename E> // E is the element type.
class Queue {
public:
// Creates an empty queue.
Queue() : head_(NULL), last_(NULL), size_(0) {}
// D'tor. Clears the queue.
~Queue() { Clear(); }
// Clears the queue.
void Clear() {
if (size_ > 0) {
// 1. Deletes every node.
QueueNode<E>* node = head_;
QueueNode<E>* next = node->next();
for (; ;) {
delete node;
node = next;
if (node == NULL) break;
next = node->next();
}
// 2. Resets the member variables.
head_ = last_ = NULL;
size_ = 0;
}
}
// Gets the number of elements.
size_t Size() const { return size_; }
// Gets the first element of the queue, or NULL if the queue is empty.
QueueNode<E>* Head() { return head_; }
const QueueNode<E>* Head() const { return head_; }
// Gets the last element of the queue, or NULL if the queue is empty.
QueueNode<E>* Last() { return last_; }
const QueueNode<E>* Last() const { return last_; }
// Adds an element to the end of the queue. A copy of the element is
// created using the copy constructor, and then stored in the queue.
// Changes made to the element in the queue doesn't affect the source
// object, and vice versa.
void Enqueue(const E& element) {
QueueNode<E>* new_node = new QueueNode<E>(element);
if (size_ == 0) {
head_ = last_ = new_node;
size_ = 1;
} else {
last_->next_ = new_node;
last_ = new_node;
size_++;
}
}
// Removes the head of the queue and returns it. Returns NULL if
// the queue is empty.
E* Dequeue() {
if (size_ == 0) {
return NULL;
}
const QueueNode<E>* const old_head = head_;
head_ = head_->next_;
size_--;
if (size_ == 0) {
last_ = NULL;
}
E* element = new E(old_head->element());
delete old_head;
return element;
}
// Applies a function/functor on each element of the queue, and
// returns the result in a new queue. The original queue is not
// affected.
template <typename F>
Queue* Map(F function) const {
Queue* new_queue = new Queue();
for (const QueueNode<E>* node = head_; node != NULL; node = node->next_) {
new_queue->Enqueue(function(node->element()));
}
return new_queue;
}
private:
QueueNode<E>* head_; // The first node of the queue.
QueueNode<E>* last_; // The last node of the queue.
size_t size_; // The number of elements in the queue.
// We disallow copying a queue.
Queue(const Queue&);
const Queue& operator = (const Queue&);
};
#endif // GTEST_SAMPLES_SAMPLE3_INL_H_

View file

@ -0,0 +1,151 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
// In this example, we use a more advanced feature of Google Test called
// test fixture.
//
// A test fixture is a place to hold objects and functions shared by
// all tests in a test case. Using a test fixture avoids duplicating
// the test code necessary to initialize and cleanup those common
// objects for each test. It is also useful for defining sub-routines
// that your tests need to invoke a lot.
//
// <TechnicalDetails>
//
// The tests share the test fixture in the sense of code sharing, not
// data sharing. Each test is given its own fresh copy of the
// fixture. You cannot expect the data modified by one test to be
// passed on to another test, which is a bad idea.
//
// The reason for this design is that tests should be independent and
// repeatable. In particular, a test should not fail as the result of
// another test's failure. If one test depends on info produced by
// another test, then the two tests should really be one big test.
//
// The macros for indicating the success/failure of a test
// (EXPECT_TRUE, FAIL, etc) need to know what the current test is
// (when Google Test prints the test result, it tells you which test
// each failure belongs to). Technically, these macros invoke a
// member function of the Test class. Therefore, you cannot use them
// in a global function. That's why you should put test sub-routines
// in a test fixture.
//
// </TechnicalDetails>
#include "sample3-inl.h"
#include "gtest/gtest.h"
// To use a test fixture, derive a class from testing::Test.
class QueueTest : public testing::Test {
protected: // You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
// virtual void TearDown() {
// }
// A helper function that some test uses.
static int Double(int n) {
return 2*n;
}
// A helper function for testing Queue::Map().
void MapTester(const Queue<int> * q) {
// Creates a new queue, where each element is twice as big as the
// corresponding one in q.
const Queue<int> * const new_q = q->Map(Double);
// Verifies that the new queue has the same size as q.
ASSERT_EQ(q->Size(), new_q->Size());
// Verifies the relationship between the elements of the two queues.
for ( const QueueNode<int> * n1 = q->Head(), * n2 = new_q->Head();
n1 != NULL; n1 = n1->next(), n2 = n2->next() ) {
EXPECT_EQ(2 * n1->element(), n2->element());
}
delete new_q;
}
// Declares the variables your tests want to use.
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};
// When you have a test fixture, you define a test using TEST_F
// instead of TEST.
// Tests the default c'tor.
TEST_F(QueueTest, DefaultConstructor) {
// You can access data in the test fixture here.
EXPECT_EQ(0u, q0_.Size());
}
// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {
int * n = q0_.Dequeue();
EXPECT_TRUE(n == NULL);
n = q1_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(1, *n);
EXPECT_EQ(0u, q1_.Size());
delete n;
n = q2_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(2, *n);
EXPECT_EQ(1u, q2_.Size());
delete n;
}
// Tests the Queue::Map() function.
TEST_F(QueueTest, Map) {
MapTester(&q0_);
MapTester(&q1_);
MapTester(&q2_);
}

View file

@ -0,0 +1,46 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#include <stdio.h>
#include "sample4.h"
// Returns the current counter value, and increments it.
int Counter::Increment() {
return counter_++;
}
// Prints the current counter value to STDOUT.
void Counter::Print() const {
printf("%d", counter_);
}

View file

@ -0,0 +1,53 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)
#ifndef GTEST_SAMPLES_SAMPLE4_H_
#define GTEST_SAMPLES_SAMPLE4_H_
// A simple monotonic counter.
class Counter {
private:
int counter_;
public:
// Creates a counter that starts at 0.
Counter() : counter_(0) {}
// Returns the current counter value, and increments it.
int Increment();
// Prints the current counter value to STDOUT.
void Print() const;
};
#endif // GTEST_SAMPLES_SAMPLE4_H_

View file

@ -0,0 +1,45 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include "gtest/gtest.h"
#include "sample4.h"
// Tests the Increment() method.
TEST(Counter, Increment) {
Counter c;
// EXPECT_EQ() evaluates its arguments exactly once, so they
// can have side effects.
EXPECT_EQ(0, c.Increment());
EXPECT_EQ(1, c.Increment());
EXPECT_EQ(2, c.Increment());
}

View file

@ -0,0 +1,199 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample teaches how to reuse a test fixture in multiple test
// cases by deriving sub-fixtures from it.
//
// When you define a test fixture, you specify the name of the test
// case that will use this fixture. Therefore, a test fixture can
// be used by only one test case.
//
// Sometimes, more than one test cases may want to use the same or
// slightly different test fixtures. For example, you may want to
// make sure that all tests for a GUI library don't leak important
// system resources like fonts and brushes. In Google Test, you do
// this by putting the shared logic in a super (as in "super class")
// test fixture, and then have each test case use a fixture derived
// from this super fixture.
#include <limits.h>
#include <time.h>
#include "sample3-inl.h"
#include "gtest/gtest.h"
#include "sample1.h"
// In this sample, we want to ensure that every test finishes within
// ~5 seconds. If a test takes longer to run, we consider it a
// failure.
//
// We put the code for timing a test in a test fixture called
// "QuickTest". QuickTest is intended to be the super fixture that
// other fixtures derive from, therefore there is no test case with
// the name "QuickTest". This is OK.
//
// Later, we will derive multiple test fixtures from QuickTest.
class QuickTest : public testing::Test {
protected:
// Remember that SetUp() is run immediately before a test starts.
// This is a good place to record the start time.
virtual void SetUp() {
start_time_ = time(NULL);
}
// TearDown() is invoked immediately after a test finishes. Here we
// check if the test was too slow.
virtual void TearDown() {
// Gets the time when the test finishes
const time_t end_time = time(NULL);
// Asserts that the test took no more than ~5 seconds. Did you
// know that you can use assertions in SetUp() and TearDown() as
// well?
EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long.";
}
// The UTC time (in seconds) when the test starts
time_t start_time_;
};
// We derive a fixture named IntegerFunctionTest from the QuickTest
// fixture. All tests using this fixture will be automatically
// required to be quick.
class IntegerFunctionTest : public QuickTest {
// We don't need any more logic than already in the QuickTest fixture.
// Therefore the body is empty.
};
// Now we can write tests in the IntegerFunctionTest test case.
// Tests Factorial()
TEST_F(IntegerFunctionTest, Factorial) {
// Tests factorial of negative numbers.
EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1));
EXPECT_GT(Factorial(-10), 0);
// Tests factorial of 0.
EXPECT_EQ(1, Factorial(0));
// Tests factorial of positive numbers.
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
// Tests IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) {
// Tests negative input.
EXPECT_FALSE(IsPrime(-1));
EXPECT_FALSE(IsPrime(-2));
EXPECT_FALSE(IsPrime(INT_MIN));
// Tests some trivial cases.
EXPECT_FALSE(IsPrime(0));
EXPECT_FALSE(IsPrime(1));
EXPECT_TRUE(IsPrime(2));
EXPECT_TRUE(IsPrime(3));
// Tests positive input.
EXPECT_FALSE(IsPrime(4));
EXPECT_TRUE(IsPrime(5));
EXPECT_FALSE(IsPrime(6));
EXPECT_TRUE(IsPrime(23));
}
// The next test case (named "QueueTest") also needs to be quick, so
// we derive another fixture from QuickTest.
//
// The QueueTest test fixture has some logic and shared objects in
// addition to what's in QuickTest already. We define the additional
// stuff inside the body of the test fixture, as usual.
class QueueTest : public QuickTest {
protected:
virtual void SetUp() {
// First, we need to set up the super fixture (QuickTest).
QuickTest::SetUp();
// Second, some additional setup for this fixture.
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// By default, TearDown() inherits the behavior of
// QuickTest::TearDown(). As we have no additional cleaning work
// for QueueTest, we omit it here.
//
// virtual void TearDown() {
// QuickTest::TearDown();
// }
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};
// Now, let's write tests using the QueueTest fixture.
// Tests the default constructor.
TEST_F(QueueTest, DefaultConstructor) {
EXPECT_EQ(0u, q0_.Size());
}
// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {
int* n = q0_.Dequeue();
EXPECT_TRUE(n == NULL);
n = q1_.Dequeue();
EXPECT_TRUE(n != NULL);
EXPECT_EQ(1, *n);
EXPECT_EQ(0u, q1_.Size());
delete n;
n = q2_.Dequeue();
EXPECT_TRUE(n != NULL);
EXPECT_EQ(2, *n);
EXPECT_EQ(1u, q2_.Size());
delete n;
}
// If necessary, you can derive further test fixtures from a derived
// fixture itself. For example, you can derive another fixture from
// QueueTest. Google Test imposes no limit on how deep the hierarchy
// can be. In practice, however, you probably don't want it to be too
// deep as to be confusing.

View file

@ -0,0 +1,224 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests).
// The interface and its implementations are in this header.
#include "prime_tables.h"
#include "gtest/gtest.h"
// First, we define some factory functions for creating instances of
// the implementations. You may be able to skip this step if all your
// implementations can be constructed the same way.
template <class T>
PrimeTable* CreatePrimeTable();
template <>
PrimeTable* CreatePrimeTable<OnTheFlyPrimeTable>() {
return new OnTheFlyPrimeTable;
}
template <>
PrimeTable* CreatePrimeTable<PreCalculatedPrimeTable>() {
return new PreCalculatedPrimeTable(10000);
}
// Then we define a test fixture class template.
template <class T>
class PrimeTableTest : public testing::Test {
protected:
// The ctor calls the factory function to create a prime table
// implemented by T.
PrimeTableTest() : table_(CreatePrimeTable<T>()) {}
virtual ~PrimeTableTest() { delete table_; }
// Note that we test an implementation via the base interface
// instead of the actual implementation class. This is important
// for keeping the tests close to the real world scenario, where the
// implementation is invoked via the base interface. It avoids
// got-yas where the implementation class has a method that shadows
// a method with the same name (but slightly different argument
// types) in the base interface, for example.
PrimeTable* const table_;
};
#if GTEST_HAS_TYPED_TEST
using testing::Types;
// Google Test offers two ways for reusing tests for different types.
// The first is called "typed tests". You should use it if you
// already know *all* the types you are gonna exercise when you write
// the tests.
// To write a typed test case, first use
//
// TYPED_TEST_CASE(TestCaseName, TypeList);
//
// to declare it and specify the type parameters. As with TEST_F,
// TestCaseName must match the test fixture name.
// The list of types we want to test.
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations;
TYPED_TEST_CASE(PrimeTableTest, Implementations);
// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,
// similar to TEST_F.
TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) {
// Inside the test body, you can refer to the type parameter by
// TypeParam, and refer to the fixture class by TestFixture. We
// don't need them in this example.
// Since we are in the template world, C++ requires explicitly
// writing 'this->' when referring to members of the fixture class.
// This is something you have to learn to live with.
EXPECT_FALSE(this->table_->IsPrime(-5));
EXPECT_FALSE(this->table_->IsPrime(0));
EXPECT_FALSE(this->table_->IsPrime(1));
EXPECT_FALSE(this->table_->IsPrime(4));
EXPECT_FALSE(this->table_->IsPrime(6));
EXPECT_FALSE(this->table_->IsPrime(100));
}
TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(this->table_->IsPrime(2));
EXPECT_TRUE(this->table_->IsPrime(3));
EXPECT_TRUE(this->table_->IsPrime(5));
EXPECT_TRUE(this->table_->IsPrime(7));
EXPECT_TRUE(this->table_->IsPrime(11));
EXPECT_TRUE(this->table_->IsPrime(131));
}
TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
EXPECT_EQ(2, this->table_->GetNextPrime(0));
EXPECT_EQ(3, this->table_->GetNextPrime(2));
EXPECT_EQ(5, this->table_->GetNextPrime(3));
EXPECT_EQ(7, this->table_->GetNextPrime(5));
EXPECT_EQ(11, this->table_->GetNextPrime(7));
EXPECT_EQ(131, this->table_->GetNextPrime(128));
}
// That's it! Google Test will repeat each TYPED_TEST for each type
// in the type list specified in TYPED_TEST_CASE. Sit back and be
// happy that you don't have to define them multiple times.
#endif // GTEST_HAS_TYPED_TEST
#if GTEST_HAS_TYPED_TEST_P
using testing::Types;
// Sometimes, however, you don't yet know all the types that you want
// to test when you write the tests. For example, if you are the
// author of an interface and expect other people to implement it, you
// might want to write a set of tests to make sure each implementation
// conforms to some basic requirements, but you don't know what
// implementations will be written in the future.
//
// How can you write the tests without committing to the type
// parameters? That's what "type-parameterized tests" can do for you.
// It is a bit more involved than typed tests, but in return you get a
// test pattern that can be reused in many contexts, which is a big
// win. Here's how you do it:
// First, define a test fixture class template. Here we just reuse
// the PrimeTableTest fixture defined earlier:
template <class T>
class PrimeTableTest2 : public PrimeTableTest<T> {
};
// Then, declare the test case. The argument is the name of the test
// fixture, and also the name of the test case (as usual). The _P
// suffix is for "parameterized" or "pattern".
TYPED_TEST_CASE_P(PrimeTableTest2);
// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,
// similar to what you do with TEST_F.
TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) {
EXPECT_FALSE(this->table_->IsPrime(-5));
EXPECT_FALSE(this->table_->IsPrime(0));
EXPECT_FALSE(this->table_->IsPrime(1));
EXPECT_FALSE(this->table_->IsPrime(4));
EXPECT_FALSE(this->table_->IsPrime(6));
EXPECT_FALSE(this->table_->IsPrime(100));
}
TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) {
EXPECT_TRUE(this->table_->IsPrime(2));
EXPECT_TRUE(this->table_->IsPrime(3));
EXPECT_TRUE(this->table_->IsPrime(5));
EXPECT_TRUE(this->table_->IsPrime(7));
EXPECT_TRUE(this->table_->IsPrime(11));
EXPECT_TRUE(this->table_->IsPrime(131));
}
TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) {
EXPECT_EQ(2, this->table_->GetNextPrime(0));
EXPECT_EQ(3, this->table_->GetNextPrime(2));
EXPECT_EQ(5, this->table_->GetNextPrime(3));
EXPECT_EQ(7, this->table_->GetNextPrime(5));
EXPECT_EQ(11, this->table_->GetNextPrime(7));
EXPECT_EQ(131, this->table_->GetNextPrime(128));
}
// Type-parameterized tests involve one extra step: you have to
// enumerate the tests you defined:
REGISTER_TYPED_TEST_CASE_P(
PrimeTableTest2, // The first argument is the test case name.
// The rest of the arguments are the test names.
ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime);
// At this point the test pattern is done. However, you don't have
// any real test yet as you haven't said which types you want to run
// the tests with.
// To turn the abstract test pattern into real tests, you instantiate
// it with a list of types. Usually the test pattern will be defined
// in a .h file, and anyone can #include and instantiate it. You can
// even instantiate it more than once in the same program. To tell
// different instances apart, you give each of them a name, which will
// become part of the test case name and can be used in test filters.
// The list of types we want to test. Note that it doesn't have to be
// defined at the time we write the TYPED_TEST_P()s.
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable>
PrimeTableImplementations;
INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated, // Instance name
PrimeTableTest2, // Test case name
PrimeTableImplementations); // Type list
#endif // GTEST_HAS_TYPED_TEST_P

View file

@ -0,0 +1,130 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using
// value-parameterized tests. Each test in the test case has
// a parameter that is an interface pointer to an implementation
// tested.
// The interface and its implementations are in this header.
#include "prime_tables.h"
#include "gtest/gtest.h"
#if GTEST_HAS_PARAM_TEST
using ::testing::TestWithParam;
using ::testing::Values;
// As a general rule, to prevent a test from affecting the tests that come
// after it, you should create and destroy the tested objects for each test
// instead of reusing them. In this sample we will define a simple factory
// function for PrimeTable objects. We will instantiate objects in test's
// SetUp() method and delete them in TearDown() method.
typedef PrimeTable* CreatePrimeTableFunc();
PrimeTable* CreateOnTheFlyPrimeTable() {
return new OnTheFlyPrimeTable();
}
template <size_t max_precalculated>
PrimeTable* CreatePreCalculatedPrimeTable() {
return new PreCalculatedPrimeTable(max_precalculated);
}
// Inside the test body, fixture constructor, SetUp(), and TearDown() you
// can refer to the test parameter by GetParam(). In this case, the test
// parameter is a factory function which we call in fixture's SetUp() to
// create and store an instance of PrimeTable.
class PrimeTableTest : public TestWithParam<CreatePrimeTableFunc*> {
public:
virtual ~PrimeTableTest() { delete table_; }
virtual void SetUp() { table_ = (*GetParam())(); }
virtual void TearDown() {
delete table_;
table_ = NULL;
}
protected:
PrimeTable* table_;
};
TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1));
EXPECT_FALSE(table_->IsPrime(4));
EXPECT_FALSE(table_->IsPrime(6));
EXPECT_FALSE(table_->IsPrime(100));
}
TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5));
EXPECT_TRUE(table_->IsPrime(7));
EXPECT_TRUE(table_->IsPrime(11));
EXPECT_TRUE(table_->IsPrime(131));
}
TEST_P(PrimeTableTest, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3));
EXPECT_EQ(7, table_->GetNextPrime(5));
EXPECT_EQ(11, table_->GetNextPrime(7));
EXPECT_EQ(131, table_->GetNextPrime(128));
}
// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of two PrimeTable object
// factory functions:
INSTANTIATE_TEST_CASE_P(
OnTheFlyAndPreCalculated,
PrimeTableTest,
Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>));
#else
// Google Test may not support value-parameterized tests with some
// compilers. If we use conditional compilation to compile out all
// code referring to the gtest_main library, MSVC linker will not link
// that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point
// must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_PARAM_TEST

View file

@ -0,0 +1,173 @@
// Copyright 2008 Google Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags,
// and each test is given one combination as a parameter.
// Use class definitions to test from this header.
#include "prime_tables.h"
#include "gtest/gtest.h"
#if GTEST_HAS_COMBINE
// Suppose we want to introduce a new, improved implementation of PrimeTable
// which combines speed of PrecalcPrimeTable and versatility of
// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
// appropriate under the circumstances. But in low memory conditions, it can be
// told to instantiate without PrecalcPrimeTable instance at all and use only
// OnTheFlyPrimeTable.
class HybridPrimeTable : public PrimeTable {
public:
HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
: on_the_fly_impl_(new OnTheFlyPrimeTable),
precalc_impl_(force_on_the_fly ? NULL :
new PreCalculatedPrimeTable(max_precalculated)),
max_precalculated_(max_precalculated) {}
virtual ~HybridPrimeTable() {
delete on_the_fly_impl_;
delete precalc_impl_;
}
virtual bool IsPrime(int n) const {
if (precalc_impl_ != NULL && n < max_precalculated_)
return precalc_impl_->IsPrime(n);
else
return on_the_fly_impl_->IsPrime(n);
}
virtual int GetNextPrime(int p) const {
int next_prime = -1;
if (precalc_impl_ != NULL && p < max_precalculated_)
next_prime = precalc_impl_->GetNextPrime(p);
return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
}
private:
OnTheFlyPrimeTable* on_the_fly_impl_;
PreCalculatedPrimeTable* precalc_impl_;
int max_precalculated_;
};
using ::testing::TestWithParam;
using ::testing::Bool;
using ::testing::Values;
using ::testing::Combine;
// To test all code paths for HybridPrimeTable we must test it with numbers
// both within and outside PreCalculatedPrimeTable's capacity and also with
// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
// accept different combinations of parameters for instantiating a
// HybridPrimeTable instance.
class PrimeTableTest : public TestWithParam< ::std::tr1::tuple<bool, int> > {
protected:
virtual void SetUp() {
// This can be written as
//
// bool force_on_the_fly;
// int max_precalculated;
// tie(force_on_the_fly, max_precalculated) = GetParam();
//
// once the Google C++ Style Guide allows use of ::std::tr1::tie.
//
bool force_on_the_fly = ::std::tr1::get<0>(GetParam());
int max_precalculated = ::std::tr1::get<1>(GetParam());
table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
}
virtual void TearDown() {
delete table_;
table_ = NULL;
}
HybridPrimeTable* table_;
};
TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
// Inside the test body, you can refer to the test parameter by GetParam().
// In this case, the test parameter is a PrimeTable interface pointer which
// we can use directly.
// Please note that you can also save it in the fixture's SetUp() method
// or constructor and use saved copy in the tests.
EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1));
EXPECT_FALSE(table_->IsPrime(4));
EXPECT_FALSE(table_->IsPrime(6));
EXPECT_FALSE(table_->IsPrime(100));
}
TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5));
EXPECT_TRUE(table_->IsPrime(7));
EXPECT_TRUE(table_->IsPrime(11));
EXPECT_TRUE(table_->IsPrime(131));
}
TEST_P(PrimeTableTest, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3));
EXPECT_EQ(7, table_->GetNextPrime(5));
EXPECT_EQ(11, table_->GetNextPrime(7));
EXPECT_EQ(131, table_->GetNextPrime(128));
}
// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of parameters. We must combine
// all variations of the boolean flag suppressing PrecalcPrimeTable and some
// meaningful values for tests. We choose a small value (1), and a value that
// will put some of the tested numbers beyond the capability of the
// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
// possible combinations.
INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,
PrimeTableTest,
Combine(Bool(), Values(1, 10)));
#else
// Google Test may not support Combine() with some compilers. If we
// use conditional compilation to compile out all code referring to
// the gtest_main library, MSVC linker will not link that library at
// all and consequently complain about missing entry point defined in
// that library (fatal error LNK1561: entry point must be
// defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_COMBINE

View file

@ -0,0 +1,160 @@
// Copyright 2009 Google Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)
// This sample shows how to use Google Test listener API to implement
// an alternative console output and how to use the UnitTest reflection API
// to enumerate test cases and tests and to inspect their results.
#include <stdio.h>
#include "gtest/gtest.h"
using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners;
using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;
namespace {
// Provides alternative output mode which produces minimal amount of
// information about tests.
class TersePrinter : public EmptyTestEventListener {
private:
// Called before any test activity starts.
virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {}
// Called after all test activities have ended.
virtual void OnTestProgramEnd(const UnitTest& unit_test) {
fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED");
fflush(stdout);
}
// Called before a test starts.
virtual void OnTestStart(const TestInfo& test_info) {
fprintf(stdout,
"*** Test %s.%s starting.\n",
test_info.test_case_name(),
test_info.name());
fflush(stdout);
}
// Called after a failed assertion or a SUCCEED() invocation.
virtual void OnTestPartResult(const TestPartResult& test_part_result) {
fprintf(stdout,
"%s in %s:%d\n%s\n",
test_part_result.failed() ? "*** Failure" : "Success",
test_part_result.file_name(),
test_part_result.line_number(),
test_part_result.summary());
fflush(stdout);
}
// Called after a test ends.
virtual void OnTestEnd(const TestInfo& test_info) {
fprintf(stdout,
"*** Test %s.%s ending.\n",
test_info.test_case_name(),
test_info.name());
fflush(stdout);
}
}; // class TersePrinter
TEST(CustomOutputTest, PrintsMessage) {
printf("Printing something from the test body...\n");
}
TEST(CustomOutputTest, Succeeds) {
SUCCEED() << "SUCCEED() has been invoked from here";
}
TEST(CustomOutputTest, Fails) {
EXPECT_EQ(1, 2)
<< "This test fails in order to demonstrate alternative failure messages";
}
} // namespace
int main(int argc, char **argv) {
InitGoogleTest(&argc, argv);
bool terse_output = false;
if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 )
terse_output = true;
else
printf("%s\n", "Run this program with --terse_output to change the way "
"it prints its output.");
UnitTest& unit_test = *UnitTest::GetInstance();
// If we are given the --terse_output command line flag, suppresses the
// standard output and attaches own result printer.
if (terse_output) {
TestEventListeners& listeners = unit_test.listeners();
// Removes the default console output listener from the list so it will
// not receive events from Google Test and won't print any output. Since
// this operation transfers ownership of the listener to the caller we
// have to delete it as well.
delete listeners.Release(listeners.default_result_printer());
// Adds the custom output listener to the list. It will now receive
// events from Google Test and print the alternative output. We don't
// have to worry about deleting it since Google Test assumes ownership
// over it after adding it to the list.
listeners.Append(new TersePrinter);
}
int ret_val = RUN_ALL_TESTS();
// This is an example of using the UnitTest reflection API to inspect test
// results. Here we discount failures from the tests we expected to fail.
int unexpectedly_failed_tests = 0;
for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
const TestCase& test_case = *unit_test.GetTestCase(i);
for (int j = 0; j < test_case.total_test_count(); ++j) {
const TestInfo& test_info = *test_case.GetTestInfo(j);
// Counts failed tests that were not meant to fail (those without
// 'Fails' in the name).
if (test_info.result()->Failed() &&
strcmp(test_info.name(), "Fails") != 0) {
unexpectedly_failed_tests++;
}
}
}
// Test that were meant to fail should not affect the test program outcome.
if (unexpectedly_failed_tests == 0)
ret_val = 0;
return ret_val;
}

View file

@ -0,0 +1,250 @@
#!/usr/bin/env python
#
# Copyright 2009, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""fuse_gtest_files.py v0.2.0
Fuses Google Test source code into a .h file and a .cc file.
SYNOPSIS
fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR
Scans GTEST_ROOT_DIR for Google Test source code, and generates
two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc.
Then you can build your tests by adding OUTPUT_DIR to the include
search path and linking with OUTPUT_DIR/gtest/gtest-all.cc. These
two files contain everything you need to use Google Test. Hence
you can "install" Google Test by copying them to wherever you want.
GTEST_ROOT_DIR can be omitted and defaults to the parent
directory of the directory holding this script.
EXAMPLES
./fuse_gtest_files.py fused_gtest
./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest
This tool is experimental. In particular, it assumes that there is no
conditional inclusion of Google Test headers. Please report any
problems to googletestframework@googlegroups.com. You can read
http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for
more information.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sets
import sys
# We assume that this file is in the scripts/ directory in the Google
# Test root directory.
DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
# Regex for matching '#include "gtest/..."'.
INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gtest/.+)"')
# Regex for matching '#include "src/..."'.
INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"')
# Where to find the source seed files.
GTEST_H_SEED = 'include/gtest/gtest.h'
GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h'
GTEST_ALL_CC_SEED = 'src/gtest-all.cc'
# Where to put the generated files.
GTEST_H_OUTPUT = 'gtest/gtest.h'
GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc'
def VerifyFileExists(directory, relative_path):
"""Verifies that the given file exists; aborts on failure.
relative_path is the file path relative to the given directory.
"""
if not os.path.isfile(os.path.join(directory, relative_path)):
print 'ERROR: Cannot find %s in directory %s.' % (relative_path,
directory)
print ('Please either specify a valid project root directory '
'or omit it on the command line.')
sys.exit(1)
def ValidateGTestRootDir(gtest_root):
"""Makes sure gtest_root points to a valid gtest root directory.
The function aborts the program on failure.
"""
VerifyFileExists(gtest_root, GTEST_H_SEED)
VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED)
def VerifyOutputFile(output_dir, relative_path):
"""Verifies that the given output file path is valid.
relative_path is relative to the output_dir directory.
"""
# Makes sure the output file either doesn't exist or can be overwritten.
output_file = os.path.join(output_dir, relative_path)
if os.path.exists(output_file):
# TODO(wan@google.com): The following user-interaction doesn't
# work with automated processes. We should provide a way for the
# Makefile to force overwriting the files.
print ('%s already exists in directory %s - overwrite it? (y/N) ' %
(relative_path, output_dir))
answer = sys.stdin.readline().strip()
if answer not in ['y', 'Y']:
print 'ABORTED.'
sys.exit(1)
# Makes sure the directory holding the output file exists; creates
# it and all its ancestors if necessary.
parent_directory = os.path.dirname(output_file)
if not os.path.isdir(parent_directory):
os.makedirs(parent_directory)
def ValidateOutputDir(output_dir):
"""Makes sure output_dir points to a valid output directory.
The function aborts the program on failure.
"""
VerifyOutputFile(output_dir, GTEST_H_OUTPUT)
VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT)
def FuseGTestH(gtest_root, output_dir):
"""Scans folder gtest_root to generate gtest/gtest.h in output_dir."""
output_file = file(os.path.join(output_dir, GTEST_H_OUTPUT), 'w')
processed_files = sets.Set() # Holds all gtest headers we've processed.
def ProcessFile(gtest_header_path):
"""Processes the given gtest header file."""
# We don't process the same header twice.
if gtest_header_path in processed_files:
return
processed_files.add(gtest_header_path)
# Reads each line in the given gtest header.
for line in file(os.path.join(gtest_root, gtest_header_path), 'r'):
m = INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
# It's '#include "gtest/..."' - let's process it recursively.
ProcessFile('include/' + m.group(1))
else:
# Otherwise we copy the line unchanged to the output file.
output_file.write(line)
ProcessFile(GTEST_H_SEED)
output_file.close()
def FuseGTestAllCcToFile(gtest_root, output_file):
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_file."""
processed_files = sets.Set()
def ProcessFile(gtest_source_file):
"""Processes the given gtest source file."""
# We don't process the same #included file twice.
if gtest_source_file in processed_files:
return
processed_files.add(gtest_source_file)
# Reads each line in the given gtest source file.
for line in file(os.path.join(gtest_root, gtest_source_file), 'r'):
m = INCLUDE_GTEST_FILE_REGEX.match(line)
if m:
if 'include/' + m.group(1) == GTEST_SPI_H_SEED:
# It's '#include "gtest/gtest-spi.h"'. This file is not
# #included by "gtest/gtest.h", so we need to process it.
ProcessFile(GTEST_SPI_H_SEED)
else:
# It's '#include "gtest/foo.h"' where foo is not gtest-spi.
# We treat it as '#include "gtest/gtest.h"', as all other
# gtest headers are being fused into gtest.h and cannot be
# #included directly.
# There is no need to #include "gtest/gtest.h" more than once.
if not GTEST_H_SEED in processed_files:
processed_files.add(GTEST_H_SEED)
output_file.write('#include "%s"\n' % (GTEST_H_OUTPUT,))
else:
m = INCLUDE_SRC_FILE_REGEX.match(line)
if m:
# It's '#include "src/foo"' - let's process it recursively.
ProcessFile(m.group(1))
else:
output_file.write(line)
ProcessFile(GTEST_ALL_CC_SEED)
def FuseGTestAllCc(gtest_root, output_dir):
"""Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir."""
output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w')
FuseGTestAllCcToFile(gtest_root, output_file)
output_file.close()
def FuseGTest(gtest_root, output_dir):
"""Fuses gtest.h and gtest-all.cc."""
ValidateGTestRootDir(gtest_root)
ValidateOutputDir(output_dir)
FuseGTestH(gtest_root, output_dir)
FuseGTestAllCc(gtest_root, output_dir)
def main():
argc = len(sys.argv)
if argc == 2:
# fuse_gtest_files.py OUTPUT_DIR
FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1])
elif argc == 3:
# fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR
FuseGTest(sys.argv[1], sys.argv[2])
else:
print __doc__
sys.exit(1)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,730 @@
#!/usr/bin/env python
#
# Copyright 2006, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""gen_gtest_pred_impl.py v0.1
Generates the implementation of Google Test predicate assertions and
accompanying tests.
Usage:
gen_gtest_pred_impl.py MAX_ARITY
where MAX_ARITY is a positive integer.
The command generates the implementation of up-to MAX_ARITY-ary
predicate assertions, and writes it to file gtest_pred_impl.h in the
directory where the script is. It also generates the accompanying
unit test in file gtest_pred_impl_unittest.cc.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import sys
import time
# Where this script is.
SCRIPT_DIR = os.path.dirname(sys.argv[0])
# Where to store the generated header.
HEADER = os.path.join(SCRIPT_DIR, '../include/gtest/gtest_pred_impl.h')
# Where to store the generated unit test.
UNIT_TEST = os.path.join(SCRIPT_DIR, '../test/gtest_pred_impl_unittest.cc')
def HeaderPreamble(n):
"""Returns the preamble for the header file.
Args:
n: the maximum arity of the predicate macros to be generated.
"""
# A map that defines the values used in the preamble template.
DEFS = {
'today' : time.strftime('%m/%d/%Y'),
'year' : time.strftime('%Y'),
'command' : '%s %s' % (os.path.basename(sys.argv[0]), n),
'n' : n
}
return (
"""// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on %(today)s by command
// '%(command)s'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h.
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion
// macros:
//
// ASSERT_PRED_FORMAT1(pred_format, v1)
// ASSERT_PRED_FORMAT2(pred_format, v1, v2)
// ...
//
// where pred_format is a function or functor that takes n (in the
// case of ASSERT_PRED_FORMATn) values and their source expression
// text, and returns a testing::AssertionResult. See the definition
// of ASSERT_EQ in gtest.h for an example.
//
// If you don't care about formatting, you can use the more
// restrictive version:
//
// ASSERT_PRED1(pred, v1)
// ASSERT_PRED2(pred, v1, v2)
// ...
//
// where pred is an n-ary function or functor that returns bool,
// and the values v1, v2, ..., must support the << operator for
// streaming to std::ostream.
//
// We also define the EXPECT_* variations.
//
// For now we only support predicates whose arity is at most %(n)s.
// Please email googletestframework@googlegroups.com if you need
// support for higher arities.
// GTEST_ASSERT_ is the basic statement to which all of the assertions
// in this file reduce. Don't use this in your code.
#define GTEST_ASSERT_(expression, on_failure) \\
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \\
if (const ::testing::AssertionResult gtest_ar = (expression)) \\
; \\
else \\
on_failure(gtest_ar.failure_message())
""" % DEFS)
def Arity(n):
"""Returns the English name of the given arity."""
if n < 0:
return None
elif n <= 3:
return ['nullary', 'unary', 'binary', 'ternary'][n]
else:
return '%s-ary' % n
def Title(word):
"""Returns the given word in title case. The difference between
this and string's title() method is that Title('4-ary') is '4-ary'
while '4-ary'.title() is '4-Ary'."""
return word[0].upper() + word[1:]
def OneTo(n):
"""Returns the list [1, 2, 3, ..., n]."""
return range(1, n + 1)
def Iter(n, format, sep=''):
"""Given a positive integer n, a format string that contains 0 or
more '%s' format specs, and optionally a separator string, returns
the join of n strings, each formatted with the format string on an
iterator ranged from 1 to n.
Example:
Iter(3, 'v%s', sep=', ') returns 'v1, v2, v3'.
"""
# How many '%s' specs are in format?
spec_count = len(format.split('%s')) - 1
return sep.join([format % (spec_count * (i,)) for i in OneTo(n)])
def ImplementationForArity(n):
"""Returns the implementation of n-ary predicate assertions."""
# A map the defines the values used in the implementation template.
DEFS = {
'n' : str(n),
'vs' : Iter(n, 'v%s', sep=', '),
'vts' : Iter(n, '#v%s', sep=', '),
'arity' : Arity(n),
'Arity' : Title(Arity(n))
}
impl = """
// Helper function for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use
// this in your code.
template <typename Pred""" % DEFS
impl += Iter(n, """,
typename T%s""")
impl += """>
AssertionResult AssertPred%(n)sHelper(const char* pred_text""" % DEFS
impl += Iter(n, """,
const char* e%s""")
impl += """,
Pred pred"""
impl += Iter(n, """,
const T%s& v%s""")
impl += """) {
if (pred(%(vs)s)) return AssertionSuccess();
""" % DEFS
impl += ' return AssertionFailure() << pred_text << "("'
impl += Iter(n, """
<< e%s""", sep=' << ", "')
impl += ' << ") evaluates to false, where"'
impl += Iter(n, """
<< "\\n" << e%s << " evaluates to " << v%s""")
impl += """;
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
// Don't use this in your code.
#define GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, on_failure)\\
GTEST_ASSERT_(pred_format(%(vts)s, %(vs)s), \\
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED%(n)s. Don't use
// this in your code.
#define GTEST_PRED%(n)s_(pred, %(vs)s, on_failure)\\
GTEST_ASSERT_(::testing::AssertPred%(n)sHelper(#pred""" % DEFS
impl += Iter(n, """, \\
#v%s""")
impl += """, \\
pred"""
impl += Iter(n, """, \\
v%s""")
impl += """), on_failure)
// %(Arity)s predicate assertion macros.
#define EXPECT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED%(n)s(pred, %(vs)s) \\
GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT%(n)s(pred_format, %(vs)s) \\
GTEST_PRED_FORMAT%(n)s_(pred_format, %(vs)s, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED%(n)s(pred, %(vs)s) \\
GTEST_PRED%(n)s_(pred, %(vs)s, GTEST_FATAL_FAILURE_)
""" % DEFS
return impl
def HeaderPostamble():
"""Returns the postamble for the header file."""
return """
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
"""
def GenerateFile(path, content):
"""Given a file path and a content string, overwrites it with the
given content."""
print 'Updating file %s . . .' % path
f = file(path, 'w+')
print >>f, content,
f.close()
print 'File %s has been updated.' % path
def GenerateHeader(n):
"""Given the maximum arity n, updates the header file that implements
the predicate assertions."""
GenerateFile(HEADER,
HeaderPreamble(n)
+ ''.join([ImplementationForArity(i) for i in OneTo(n)])
+ HeaderPostamble())
def UnitTestPreamble():
"""Returns the preamble for the unit test file."""
# A map that defines the values used in the preamble template.
DEFS = {
'today' : time.strftime('%m/%d/%Y'),
'year' : time.strftime('%Y'),
'command' : '%s %s' % (os.path.basename(sys.argv[0]), sys.argv[1]),
}
return (
"""// Copyright 2006, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on %(today)s by command
// '%(command)s'. DO NOT EDIT BY HAND!
// Regression test for gtest_pred_impl.h
//
// This file is generated by a script and quite long. If you intend to
// learn how Google Test works by reading its unit tests, read
// gtest_unittest.cc instead.
//
// This is intended as a regression test for the Google Test predicate
// assertions. We compile it as part of the gtest_unittest target
// only to keep the implementation tidy and compact, as it is quite
// involved to set up the stage for testing Google Test using Google
// Test itself.
//
// Currently, gtest_unittest takes ~11 seconds to run in the testing
// daemon. In the future, if it grows too large and needs much more
// time to finish, we should consider separating this file into a
// stand-alone regression test.
#include <iostream>
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
// A user-defined data type.
struct Bool {
explicit Bool(int val) : value(val != 0) {}
bool operator>(int n) const { return value > Bool(n).value; }
Bool operator+(const Bool& rhs) const { return Bool(value + rhs.value); }
bool operator==(const Bool& rhs) const { return value == rhs.value; }
bool value;
};
// Enables Bool to be used in assertions.
std::ostream& operator<<(std::ostream& os, const Bool& x) {
return os << (x.value ? "true" : "false");
}
""" % DEFS)
def TestsForArity(n):
"""Returns the tests for n-ary predicate assertions."""
# A map that defines the values used in the template for the tests.
DEFS = {
'n' : n,
'es' : Iter(n, 'e%s', sep=', '),
'vs' : Iter(n, 'v%s', sep=', '),
'vts' : Iter(n, '#v%s', sep=', '),
'tvs' : Iter(n, 'T%s v%s', sep=', '),
'int_vs' : Iter(n, 'int v%s', sep=', '),
'Bool_vs' : Iter(n, 'Bool v%s', sep=', '),
'types' : Iter(n, 'typename T%s', sep=', '),
'v_sum' : Iter(n, 'v%s', sep=' + '),
'arity' : Arity(n),
'Arity' : Title(Arity(n)),
}
tests = (
"""// Sample functions/functors for testing %(arity)s predicate assertions.
// A %(arity)s predicate function.
template <%(types)s>
bool PredFunction%(n)s(%(tvs)s) {
return %(v_sum)s > 0;
}
// The following two functions are needed to circumvent a bug in
// gcc 2.95.3, which sometimes has problem with the above template
// function.
bool PredFunction%(n)sInt(%(int_vs)s) {
return %(v_sum)s > 0;
}
bool PredFunction%(n)sBool(%(Bool_vs)s) {
return %(v_sum)s > 0;
}
""" % DEFS)
tests += """
// A %(arity)s predicate functor.
struct PredFunctor%(n)s {
template <%(types)s>
bool operator()(""" % DEFS
tests += Iter(n, 'const T%s& v%s', sep=""",
""")
tests += """) {
return %(v_sum)s > 0;
}
};
""" % DEFS
tests += """
// A %(arity)s predicate-formatter function.
template <%(types)s>
testing::AssertionResult PredFormatFunction%(n)s(""" % DEFS
tests += Iter(n, 'const char* e%s', sep=""",
""")
tests += Iter(n, """,
const T%s& v%s""")
tests += """) {
if (PredFunction%(n)s(%(vs)s))
return testing::AssertionSuccess();
return testing::AssertionFailure()
<< """ % DEFS
tests += Iter(n, 'e%s', sep=' << " + " << ')
tests += """
<< " is expected to be positive, but evaluates to "
<< %(v_sum)s << ".";
}
""" % DEFS
tests += """
// A %(arity)s predicate-formatter functor.
struct PredFormatFunctor%(n)s {
template <%(types)s>
testing::AssertionResult operator()(""" % DEFS
tests += Iter(n, 'const char* e%s', sep=""",
""")
tests += Iter(n, """,
const T%s& v%s""")
tests += """) const {
return PredFormatFunction%(n)s(%(es)s, %(vs)s);
}
};
""" % DEFS
tests += """
// Tests for {EXPECT|ASSERT}_PRED_FORMAT%(n)s.
class Predicate%(n)sTest : public testing::Test {
protected:
virtual void SetUp() {
expected_to_finish_ = true;
finished_ = false;""" % DEFS
tests += """
""" + Iter(n, 'n%s_ = ') + """0;
}
"""
tests += """
virtual void TearDown() {
// Verifies that each of the predicate's arguments was evaluated
// exactly once."""
tests += ''.join(["""
EXPECT_EQ(1, n%s_) <<
"The predicate assertion didn't evaluate argument %s "
"exactly once.";""" % (i, i + 1) for i in OneTo(n)])
tests += """
// Verifies that the control flow in the test function is expected.
if (expected_to_finish_ && !finished_) {
FAIL() << "The predicate assertion unexpactedly aborted the test.";
} else if (!expected_to_finish_ && finished_) {
FAIL() << "The failed predicate assertion didn't abort the test "
"as expected.";
}
}
// true iff the test function is expected to run to finish.
static bool expected_to_finish_;
// true iff the test function did run to finish.
static bool finished_;
""" % DEFS
tests += Iter(n, """
static int n%s_;""")
tests += """
};
bool Predicate%(n)sTest::expected_to_finish_;
bool Predicate%(n)sTest::finished_;
""" % DEFS
tests += Iter(n, """int Predicate%%(n)sTest::n%s_;
""") % DEFS
tests += """
typedef Predicate%(n)sTest EXPECT_PRED_FORMAT%(n)sTest;
typedef Predicate%(n)sTest ASSERT_PRED_FORMAT%(n)sTest;
typedef Predicate%(n)sTest EXPECT_PRED%(n)sTest;
typedef Predicate%(n)sTest ASSERT_PRED%(n)sTest;
""" % DEFS
def GenTest(use_format, use_assert, expect_failure,
use_functor, use_user_type):
"""Returns the test for a predicate assertion macro.
Args:
use_format: true iff the assertion is a *_PRED_FORMAT*.
use_assert: true iff the assertion is a ASSERT_*.
expect_failure: true iff the assertion is expected to fail.
use_functor: true iff the first argument of the assertion is
a functor (as opposed to a function)
use_user_type: true iff the predicate functor/function takes
argument(s) of a user-defined type.
Example:
GenTest(1, 0, 0, 1, 0) returns a test that tests the behavior
of a successful EXPECT_PRED_FORMATn() that takes a functor
whose arguments have built-in types."""
if use_assert:
assrt = 'ASSERT' # 'assert' is reserved, so we cannot use
# that identifier here.
else:
assrt = 'EXPECT'
assertion = assrt + '_PRED'
if use_format:
pred_format = 'PredFormat'
assertion += '_FORMAT'
else:
pred_format = 'Pred'
assertion += '%(n)s' % DEFS
if use_functor:
pred_format_type = 'functor'
pred_format += 'Functor%(n)s()'
else:
pred_format_type = 'function'
pred_format += 'Function%(n)s'
if not use_format:
if use_user_type:
pred_format += 'Bool'
else:
pred_format += 'Int'
test_name = pred_format_type.title()
if use_user_type:
arg_type = 'user-defined type (Bool)'
test_name += 'OnUserType'
if expect_failure:
arg = 'Bool(n%s_++)'
else:
arg = 'Bool(++n%s_)'
else:
arg_type = 'built-in type (int)'
test_name += 'OnBuiltInType'
if expect_failure:
arg = 'n%s_++'
else:
arg = '++n%s_'
if expect_failure:
successful_or_failed = 'failed'
expected_or_not = 'expected.'
test_name += 'Failure'
else:
successful_or_failed = 'successful'
expected_or_not = 'UNEXPECTED!'
test_name += 'Success'
# A map that defines the values used in the test template.
defs = DEFS.copy()
defs.update({
'assert' : assrt,
'assertion' : assertion,
'test_name' : test_name,
'pf_type' : pred_format_type,
'pf' : pred_format,
'arg_type' : arg_type,
'arg' : arg,
'successful' : successful_or_failed,
'expected' : expected_or_not,
})
test = """
// Tests a %(successful)s %(assertion)s where the
// predicate-formatter is a %(pf_type)s on a %(arg_type)s.
TEST_F(%(assertion)sTest, %(test_name)s) {""" % defs
indent = (len(assertion) + 3)*' '
extra_indent = ''
if expect_failure:
extra_indent = ' '
if use_assert:
test += """
expected_to_finish_ = false;
EXPECT_FATAL_FAILURE({ // NOLINT"""
else:
test += """
EXPECT_NONFATAL_FAILURE({ // NOLINT"""
test += '\n' + extra_indent + """ %(assertion)s(%(pf)s""" % defs
test = test % defs
test += Iter(n, ',\n' + indent + extra_indent + '%(arg)s' % defs)
test += ');\n' + extra_indent + ' finished_ = true;\n'
if expect_failure:
test += ' }, "");\n'
test += '}\n'
return test
# Generates tests for all 2**6 = 64 combinations.
tests += ''.join([GenTest(use_format, use_assert, expect_failure,
use_functor, use_user_type)
for use_format in [0, 1]
for use_assert in [0, 1]
for expect_failure in [0, 1]
for use_functor in [0, 1]
for use_user_type in [0, 1]
])
return tests
def UnitTestPostamble():
"""Returns the postamble for the tests."""
return ''
def GenerateUnitTest(n):
"""Returns the tests for up-to n-ary predicate assertions."""
GenerateFile(UNIT_TEST,
UnitTestPreamble()
+ ''.join([TestsForArity(i) for i in OneTo(n)])
+ UnitTestPostamble())
def _Main():
"""The entry point of the script. Generates the header file and its
unit test."""
if len(sys.argv) != 2:
print __doc__
print 'Author: ' + __author__
sys.exit(1)
n = int(sys.argv[1])
GenerateHeader(n)
GenerateUnitTest(n)
if __name__ == '__main__':
_Main()

View file

@ -0,0 +1,274 @@
#!/bin/sh
# These variables are automatically filled in by the configure script.
name="@PACKAGE_TARNAME@"
version="@PACKAGE_VERSION@"
show_usage()
{
echo "Usage: gtest-config [OPTIONS...]"
}
show_help()
{
show_usage
cat <<\EOF
The `gtest-config' script provides access to the necessary compile and linking
flags to connect with Google C++ Testing Framework, both in a build prior to
installation, and on the system proper after installation. The installation
overrides may be issued in combination with any other queries, but will only
affect installation queries if called on a built but not installed gtest. The
installation queries may not be issued with any other types of queries, and
only one installation query may be made at a time. The version queries and
compiler flag queries may be combined as desired but not mixed. Different
version queries are always combined with logical "and" semantics, and only the
last of any particular query is used while all previous ones ignored. All
versions must be specified as a sequence of numbers separated by periods.
Compiler flag queries output the union of the sets of flags when combined.
Examples:
gtest-config --min-version=1.0 || echo "Insufficient Google Test version."
g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp
g++ $(gtest-config --ldflags --libs) -o foo foo.o
# When using a built but not installed Google Test:
g++ $(../../my_gtest_build/scripts/gtest-config ...) ...
# When using an installed Google Test, but with installation overrides:
export GTEST_PREFIX="/opt"
g++ $(gtest-config --libdir="/opt/lib64" ...) ...
Help:
--usage brief usage information
--help display this help message
Installation Overrides:
--prefix=<dir> overrides the installation prefix
--exec-prefix=<dir> overrides the executable installation prefix
--libdir=<dir> overrides the library installation prefix
--includedir=<dir> overrides the header file installation prefix
Installation Queries:
--prefix installation prefix
--exec-prefix executable installation prefix
--libdir library installation directory
--includedir header file installation directory
--version the version of the Google Test installation
Version Queries:
--min-version=VERSION return 0 if the version is at least VERSION
--exact-version=VERSION return 0 if the version is exactly VERSION
--max-version=VERSION return 0 if the version is at most VERSION
Compilation Flag Queries:
--cppflags compile flags specific to the C-like preprocessors
--cxxflags compile flags appropriate for C++ programs
--ldflags linker flags
--libs libraries for linking
EOF
}
# This function bounds our version with a min and a max. It uses some clever
# POSIX-compliant variable expansion to portably do all the work in the shell
# and avoid any dependency on a particular "sed" or "awk" implementation.
# Notable is that it will only ever compare the first 3 components of versions.
# Further components will be cleanly stripped off. All versions must be
# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
# continuing to maintain our own shell version.
check_versions()
{
major_version=${version%%.*}
minor_version="0"
point_version="0"
if test "${version#*.}" != "${version}"; then
minor_version=${version#*.}
minor_version=${minor_version%%.*}
fi
if test "${version#*.*.}" != "${version}"; then
point_version=${version#*.*.}
point_version=${point_version%%.*}
fi
min_version="$1"
min_major_version=${min_version%%.*}
min_minor_version="0"
min_point_version="0"
if test "${min_version#*.}" != "${min_version}"; then
min_minor_version=${min_version#*.}
min_minor_version=${min_minor_version%%.*}
fi
if test "${min_version#*.*.}" != "${min_version}"; then
min_point_version=${min_version#*.*.}
min_point_version=${min_point_version%%.*}
fi
max_version="$2"
max_major_version=${max_version%%.*}
max_minor_version="0"
max_point_version="0"
if test "${max_version#*.}" != "${max_version}"; then
max_minor_version=${max_version#*.}
max_minor_version=${max_minor_version%%.*}
fi
if test "${max_version#*.*.}" != "${max_version}"; then
max_point_version=${max_version#*.*.}
max_point_version=${max_point_version%%.*}
fi
test $(($major_version)) -lt $(($min_major_version)) && exit 1
if test $(($major_version)) -eq $(($min_major_version)); then
test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
if test $(($minor_version)) -eq $(($min_minor_version)); then
test $(($point_version)) -lt $(($min_point_version)) && exit 1
fi
fi
test $(($major_version)) -gt $(($max_major_version)) && exit 1
if test $(($major_version)) -eq $(($max_major_version)); then
test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
if test $(($minor_version)) -eq $(($max_minor_version)); then
test $(($point_version)) -gt $(($max_point_version)) && exit 1
fi
fi
exit 0
}
# Show the usage line when no arguments are specified.
if test $# -eq 0; then
show_usage
exit 1
fi
while test $# -gt 0; do
case $1 in
--usage) show_usage; exit 0;;
--help) show_help; exit 0;;
# Installation overrides
--prefix=*) GTEST_PREFIX=${1#--prefix=};;
--exec-prefix=*) GTEST_EXEC_PREFIX=${1#--exec-prefix=};;
--libdir=*) GTEST_LIBDIR=${1#--libdir=};;
--includedir=*) GTEST_INCLUDEDIR=${1#--includedir=};;
# Installation queries
--prefix|--exec-prefix|--libdir|--includedir|--version)
if test -n "${do_query}"; then
show_usage
exit 1
fi
do_query=${1#--}
;;
# Version checking
--min-version=*)
do_check_versions=yes
min_version=${1#--min-version=}
;;
--max-version=*)
do_check_versions=yes
max_version=${1#--max-version=}
;;
--exact-version=*)
do_check_versions=yes
exact_version=${1#--exact-version=}
;;
# Compiler flag output
--cppflags) echo_cppflags=yes;;
--cxxflags) echo_cxxflags=yes;;
--ldflags) echo_ldflags=yes;;
--libs) echo_libs=yes;;
# Everything else is an error
*) show_usage; exit 1;;
esac
shift
done
# These have defaults filled in by the configure script but can also be
# overridden by environment variables or command line parameters.
prefix="${GTEST_PREFIX:-@prefix@}"
exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}"
libdir="${GTEST_LIBDIR:-@libdir@}"
includedir="${GTEST_INCLUDEDIR:-@includedir@}"
# We try and detect if our binary is not located at its installed location. If
# it's not, we provide variables pointing to the source and build tree rather
# than to the install tree. This allows building against a just-built gtest
# rather than an installed gtest.
bindir="@bindir@"
this_relative_bindir=`dirname $0`
this_bindir=`cd ${this_relative_bindir}; pwd -P`
if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
# The path to the script doesn't end in the bindir sequence from Autoconf,
# assume that we are in a build tree.
build_dir=`dirname ${this_bindir}`
src_dir=`cd ${this_bindir}; cd @top_srcdir@; pwd -P`
# TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
# should work to remove it, and/or remove libtool altogether, replacing it
# with direct references to the library and a link path.
gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_ldflags=""
# We provide hooks to include from either the source or build dir, where the
# build dir is always preferred. This will potentially allow us to write
# build rules for generated headers and have them automatically be preferred
# over provided versions.
gtest_cppflags="-I${build_dir}/include -I${src_dir}/include"
gtest_cxxflags="@PTHREAD_CFLAGS@"
else
# We're using an installed gtest, although it may be staged under some
# prefix. Assume (as our own libraries do) that we can resolve the prefix,
# and are present in the dynamic link paths.
gtest_ldflags="-L${libdir}"
gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
gtest_cppflags="-I${includedir}"
gtest_cxxflags="@PTHREAD_CFLAGS@"
fi
# Do an installation query if requested.
if test -n "$do_query"; then
case $do_query in
prefix) echo $prefix; exit 0;;
exec-prefix) echo $exec_prefix; exit 0;;
libdir) echo $libdir; exit 0;;
includedir) echo $includedir; exit 0;;
version) echo $version; exit 0;;
*) show_usage; exit 1;;
esac
fi
# Do a version check if requested.
if test "$do_check_versions" = "yes"; then
# Make sure we didn't receive a bad combination of parameters.
test "$echo_cppflags" = "yes" && show_usage && exit 1
test "$echo_cxxflags" = "yes" && show_usage && exit 1
test "$echo_ldflags" = "yes" && show_usage && exit 1
test "$echo_libs" = "yes" && show_usage && exit 1
if test "$exact_version" != ""; then
check_versions $exact_version $exact_version
# unreachable
else
check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
# unreachable
fi
fi
# Do the output in the correct order so that these can be used in-line of
# a compiler invocation.
output=""
test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags"
test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags"
test "$echo_ldflags" = "yes" && output="$output $gtest_ldflags"
test "$echo_libs" = "yes" && output="$output $gtest_libs"
echo $output
exit 0

View file

@ -0,0 +1,855 @@
#!/usr/bin/env python
#
# Copyright 2008, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""pump v0.2.0 - Pretty Useful for Meta Programming.
A tool for preprocessor meta programming. Useful for generating
repetitive boilerplate code. Especially useful for writing C++
classes, functions, macros, and templates that need to work with
various number of arguments.
USAGE:
pump.py SOURCE_FILE
EXAMPLES:
pump.py foo.cc.pump
Converts foo.cc.pump to foo.cc.
GRAMMAR:
CODE ::= ATOMIC_CODE*
ATOMIC_CODE ::= $var ID = EXPRESSION
| $var ID = [[ CODE ]]
| $range ID EXPRESSION..EXPRESSION
| $for ID SEPARATOR [[ CODE ]]
| $($)
| $ID
| $(EXPRESSION)
| $if EXPRESSION [[ CODE ]] ELSE_BRANCH
| [[ CODE ]]
| RAW_CODE
SEPARATOR ::= RAW_CODE | EMPTY
ELSE_BRANCH ::= $else [[ CODE ]]
| $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
| EMPTY
EXPRESSION has Python syntax.
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sys
TOKEN_TABLE = [
(re.compile(r'\$var\s+'), '$var'),
(re.compile(r'\$elif\s+'), '$elif'),
(re.compile(r'\$else\s+'), '$else'),
(re.compile(r'\$for\s+'), '$for'),
(re.compile(r'\$if\s+'), '$if'),
(re.compile(r'\$range\s+'), '$range'),
(re.compile(r'\$[_A-Za-z]\w*'), '$id'),
(re.compile(r'\$\(\$\)'), '$($)'),
(re.compile(r'\$'), '$'),
(re.compile(r'\[\[\n?'), '[['),
(re.compile(r'\]\]\n?'), ']]'),
]
class Cursor:
"""Represents a position (line and column) in a text file."""
def __init__(self, line=-1, column=-1):
self.line = line
self.column = column
def __eq__(self, rhs):
return self.line == rhs.line and self.column == rhs.column
def __ne__(self, rhs):
return not self == rhs
def __lt__(self, rhs):
return self.line < rhs.line or (
self.line == rhs.line and self.column < rhs.column)
def __le__(self, rhs):
return self < rhs or self == rhs
def __gt__(self, rhs):
return rhs < self
def __ge__(self, rhs):
return rhs <= self
def __str__(self):
if self == Eof():
return 'EOF'
else:
return '%s(%s)' % (self.line + 1, self.column)
def __add__(self, offset):
return Cursor(self.line, self.column + offset)
def __sub__(self, offset):
return Cursor(self.line, self.column - offset)
def Clone(self):
"""Returns a copy of self."""
return Cursor(self.line, self.column)
# Special cursor to indicate the end-of-file.
def Eof():
"""Returns the special cursor to denote the end-of-file."""
return Cursor(-1, -1)
class Token:
"""Represents a token in a Pump source file."""
def __init__(self, start=None, end=None, value=None, token_type=None):
if start is None:
self.start = Eof()
else:
self.start = start
if end is None:
self.end = Eof()
else:
self.end = end
self.value = value
self.token_type = token_type
def __str__(self):
return 'Token @%s: \'%s\' type=%s' % (
self.start, self.value, self.token_type)
def Clone(self):
"""Returns a copy of self."""
return Token(self.start.Clone(), self.end.Clone(), self.value,
self.token_type)
def StartsWith(lines, pos, string):
"""Returns True iff the given position in lines starts with 'string'."""
return lines[pos.line][pos.column:].startswith(string)
def FindFirstInLine(line, token_table):
best_match_start = -1
for (regex, token_type) in token_table:
m = regex.search(line)
if m:
# We found regex in lines
if best_match_start < 0 or m.start() < best_match_start:
best_match_start = m.start()
best_match_length = m.end() - m.start()
best_match_token_type = token_type
if best_match_start < 0:
return None
return (best_match_start, best_match_length, best_match_token_type)
def FindFirst(lines, token_table, cursor):
"""Finds the first occurrence of any string in strings in lines."""
start = cursor.Clone()
cur_line_number = cursor.line
for line in lines[start.line:]:
if cur_line_number == start.line:
line = line[start.column:]
m = FindFirstInLine(line, token_table)
if m:
# We found a regex in line.
(start_column, length, token_type) = m
if cur_line_number == start.line:
start_column += start.column
found_start = Cursor(cur_line_number, start_column)
found_end = found_start + length
return MakeToken(lines, found_start, found_end, token_type)
cur_line_number += 1
# We failed to find str in lines
return None
def SubString(lines, start, end):
"""Returns a substring in lines."""
if end == Eof():
end = Cursor(len(lines) - 1, len(lines[-1]))
if start >= end:
return ''
if start.line == end.line:
return lines[start.line][start.column:end.column]
result_lines = ([lines[start.line][start.column:]] +
lines[start.line + 1:end.line] +
[lines[end.line][:end.column]])
return ''.join(result_lines)
def StripMetaComments(str):
"""Strip meta comments from each line in the given string."""
# First, completely remove lines containing nothing but a meta
# comment, including the trailing \n.
str = re.sub(r'^\s*\$\$.*\n', '', str)
# Then, remove meta comments from contentful lines.
return re.sub(r'\s*\$\$.*', '', str)
def MakeToken(lines, start, end, token_type):
"""Creates a new instance of Token."""
return Token(start, end, SubString(lines, start, end), token_type)
def ParseToken(lines, pos, regex, token_type):
line = lines[pos.line][pos.column:]
m = regex.search(line)
if m and not m.start():
return MakeToken(lines, pos, pos + m.end(), token_type)
else:
print 'ERROR: %s expected at %s.' % (token_type, pos)
sys.exit(1)
ID_REGEX = re.compile(r'[_A-Za-z]\w*')
EQ_REGEX = re.compile(r'=')
REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
WHITE_SPACE_REGEX = re.compile(r'\s')
DOT_DOT_REGEX = re.compile(r'\.\.')
def Skip(lines, pos, regex):
line = lines[pos.line][pos.column:]
m = re.search(regex, line)
if m and not m.start():
return pos + m.end()
else:
return pos
def SkipUntil(lines, pos, regex, token_type):
line = lines[pos.line][pos.column:]
m = re.search(regex, line)
if m:
return pos + m.start()
else:
print ('ERROR: %s expected on line %s after column %s.' %
(token_type, pos.line + 1, pos.column))
sys.exit(1)
def ParseExpTokenInParens(lines, pos):
def ParseInParens(pos):
pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
pos = Skip(lines, pos, r'\(')
pos = Parse(pos)
pos = Skip(lines, pos, r'\)')
return pos
def Parse(pos):
pos = SkipUntil(lines, pos, r'\(|\)', ')')
if SubString(lines, pos, pos + 1) == '(':
pos = Parse(pos + 1)
pos = Skip(lines, pos, r'\)')
return Parse(pos)
else:
return pos
start = pos.Clone()
pos = ParseInParens(pos)
return MakeToken(lines, start, pos, 'exp')
def RStripNewLineFromToken(token):
if token.value.endswith('\n'):
return Token(token.start, token.end, token.value[:-1], token.token_type)
else:
return token
def TokenizeLines(lines, pos):
while True:
found = FindFirst(lines, TOKEN_TABLE, pos)
if not found:
yield MakeToken(lines, pos, Eof(), 'code')
return
if found.start == pos:
prev_token = None
prev_token_rstripped = None
else:
prev_token = MakeToken(lines, pos, found.start, 'code')
prev_token_rstripped = RStripNewLineFromToken(prev_token)
if found.token_type == '$var':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
yield eq_token
pos = Skip(lines, eq_token.end, r'\s*')
if SubString(lines, pos, pos + 2) != '[[':
exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
yield exp_token
pos = Cursor(exp_token.end.line + 1, 0)
elif found.token_type == '$for':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
elif found.token_type == '$range':
if prev_token_rstripped:
yield prev_token_rstripped
yield found
id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
yield id_token
pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
yield MakeToken(lines, pos, dots_pos, 'exp')
yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
pos = dots_pos + 2
new_pos = Cursor(pos.line + 1, 0)
yield MakeToken(lines, pos, new_pos, 'exp')
pos = new_pos
elif found.token_type == '$':
if prev_token:
yield prev_token
yield found
exp_token = ParseExpTokenInParens(lines, found.end)
yield exp_token
pos = exp_token.end
elif (found.token_type == ']]' or found.token_type == '$if' or
found.token_type == '$elif' or found.token_type == '$else'):
if prev_token_rstripped:
yield prev_token_rstripped
yield found
pos = found.end
else:
if prev_token:
yield prev_token
yield found
pos = found.end
def Tokenize(s):
"""A generator that yields the tokens in the given string."""
if s != '':
lines = s.splitlines(True)
for token in TokenizeLines(lines, Cursor(0, 0)):
yield token
class CodeNode:
def __init__(self, atomic_code_list=None):
self.atomic_code = atomic_code_list
class VarNode:
def __init__(self, identifier=None, atomic_code=None):
self.identifier = identifier
self.atomic_code = atomic_code
class RangeNode:
def __init__(self, identifier=None, exp1=None, exp2=None):
self.identifier = identifier
self.exp1 = exp1
self.exp2 = exp2
class ForNode:
def __init__(self, identifier=None, sep=None, code=None):
self.identifier = identifier
self.sep = sep
self.code = code
class ElseNode:
def __init__(self, else_branch=None):
self.else_branch = else_branch
class IfNode:
def __init__(self, exp=None, then_branch=None, else_branch=None):
self.exp = exp
self.then_branch = then_branch
self.else_branch = else_branch
class RawCodeNode:
def __init__(self, token=None):
self.raw_code = token
class LiteralDollarNode:
def __init__(self, token):
self.token = token
class ExpNode:
def __init__(self, token, python_exp):
self.token = token
self.python_exp = python_exp
def PopFront(a_list):
head = a_list[0]
a_list[:1] = []
return head
def PushFront(a_list, elem):
a_list[:0] = [elem]
def PopToken(a_list, token_type=None):
token = PopFront(a_list)
if token_type is not None and token.token_type != token_type:
print 'ERROR: %s expected at %s' % (token_type, token.start)
print 'ERROR: %s found instead' % (token,)
sys.exit(1)
return token
def PeekToken(a_list):
if not a_list:
return None
return a_list[0]
def ParseExpNode(token):
python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
return ExpNode(token, python_exp)
def ParseElseNode(tokens):
def Pop(token_type=None):
return PopToken(tokens, token_type)
next = PeekToken(tokens)
if not next:
return None
if next.token_type == '$else':
Pop('$else')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return code_node
elif next.token_type == '$elif':
Pop('$elif')
exp = Pop('code')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
inner_else_node = ParseElseNode(tokens)
return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
elif not next.value.strip():
Pop('code')
return ParseElseNode(tokens)
else:
return None
def ParseAtomicCodeNode(tokens):
def Pop(token_type=None):
return PopToken(tokens, token_type)
head = PopFront(tokens)
t = head.token_type
if t == 'code':
return RawCodeNode(head)
elif t == '$var':
id_token = Pop('id')
Pop('=')
next = PeekToken(tokens)
if next.token_type == 'exp':
exp_token = Pop()
return VarNode(id_token, ParseExpNode(exp_token))
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return VarNode(id_token, code_node)
elif t == '$for':
id_token = Pop('id')
next_token = PeekToken(tokens)
if next_token.token_type == 'code':
sep_token = next_token
Pop('code')
else:
sep_token = None
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
return ForNode(id_token, sep_token, code_node)
elif t == '$if':
exp_token = Pop('code')
Pop('[[')
code_node = ParseCodeNode(tokens)
Pop(']]')
else_node = ParseElseNode(tokens)
return IfNode(ParseExpNode(exp_token), code_node, else_node)
elif t == '$range':
id_token = Pop('id')
exp1_token = Pop('exp')
Pop('..')
exp2_token = Pop('exp')
return RangeNode(id_token, ParseExpNode(exp1_token),
ParseExpNode(exp2_token))
elif t == '$id':
return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
elif t == '$($)':
return LiteralDollarNode(head)
elif t == '$':
exp_token = Pop('exp')
return ParseExpNode(exp_token)
elif t == '[[':
code_node = ParseCodeNode(tokens)
Pop(']]')
return code_node
else:
PushFront(tokens, head)
return None
def ParseCodeNode(tokens):
atomic_code_list = []
while True:
if not tokens:
break
atomic_code_node = ParseAtomicCodeNode(tokens)
if atomic_code_node:
atomic_code_list.append(atomic_code_node)
else:
break
return CodeNode(atomic_code_list)
def ParseToAST(pump_src_text):
"""Convert the given Pump source text into an AST."""
tokens = list(Tokenize(pump_src_text))
code_node = ParseCodeNode(tokens)
return code_node
class Env:
def __init__(self):
self.variables = []
self.ranges = []
def Clone(self):
clone = Env()
clone.variables = self.variables[:]
clone.ranges = self.ranges[:]
return clone
def PushVariable(self, var, value):
# If value looks like an int, store it as an int.
try:
int_value = int(value)
if ('%s' % int_value) == value:
value = int_value
except Exception:
pass
self.variables[:0] = [(var, value)]
def PopVariable(self):
self.variables[:1] = []
def PushRange(self, var, lower, upper):
self.ranges[:0] = [(var, lower, upper)]
def PopRange(self):
self.ranges[:1] = []
def GetValue(self, identifier):
for (var, value) in self.variables:
if identifier == var:
return value
print 'ERROR: meta variable %s is undefined.' % (identifier,)
sys.exit(1)
def EvalExp(self, exp):
try:
result = eval(exp.python_exp)
except Exception, e:
print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e)
print ('ERROR: failed to evaluate meta expression %s at %s' %
(exp.python_exp, exp.token.start))
sys.exit(1)
return result
def GetRange(self, identifier):
for (var, lower, upper) in self.ranges:
if identifier == var:
return (lower, upper)
print 'ERROR: range %s is undefined.' % (identifier,)
sys.exit(1)
class Output:
def __init__(self):
self.string = ''
def GetLastLine(self):
index = self.string.rfind('\n')
if index < 0:
return ''
return self.string[index + 1:]
def Append(self, s):
self.string += s
def RunAtomicCode(env, node, output):
if isinstance(node, VarNode):
identifier = node.identifier.value.strip()
result = Output()
RunAtomicCode(env.Clone(), node.atomic_code, result)
value = result.string
env.PushVariable(identifier, value)
elif isinstance(node, RangeNode):
identifier = node.identifier.value.strip()
lower = int(env.EvalExp(node.exp1))
upper = int(env.EvalExp(node.exp2))
env.PushRange(identifier, lower, upper)
elif isinstance(node, ForNode):
identifier = node.identifier.value.strip()
if node.sep is None:
sep = ''
else:
sep = node.sep.value
(lower, upper) = env.GetRange(identifier)
for i in range(lower, upper + 1):
new_env = env.Clone()
new_env.PushVariable(identifier, i)
RunCode(new_env, node.code, output)
if i != upper:
output.Append(sep)
elif isinstance(node, RawCodeNode):
output.Append(node.raw_code.value)
elif isinstance(node, IfNode):
cond = env.EvalExp(node.exp)
if cond:
RunCode(env.Clone(), node.then_branch, output)
elif node.else_branch is not None:
RunCode(env.Clone(), node.else_branch, output)
elif isinstance(node, ExpNode):
value = env.EvalExp(node)
output.Append('%s' % (value,))
elif isinstance(node, LiteralDollarNode):
output.Append('$')
elif isinstance(node, CodeNode):
RunCode(env.Clone(), node, output)
else:
print 'BAD'
print node
sys.exit(1)
def RunCode(env, code_node, output):
for atomic_code in code_node.atomic_code:
RunAtomicCode(env, atomic_code, output)
def IsSingleLineComment(cur_line):
return '//' in cur_line
def IsInPreprocessorDirective(prev_lines, cur_line):
if cur_line.lstrip().startswith('#'):
return True
return prev_lines and prev_lines[-1].endswith('\\')
def WrapComment(line, output):
loc = line.find('//')
before_comment = line[:loc].rstrip()
if before_comment == '':
indent = loc
else:
output.append(before_comment)
indent = len(before_comment) - len(before_comment.lstrip())
prefix = indent*' ' + '// '
max_len = 80 - len(prefix)
comment = line[loc + 2:].strip()
segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
cur_line = ''
for seg in segs:
if len((cur_line + seg).rstrip()) < max_len:
cur_line += seg
else:
if cur_line.strip() != '':
output.append(prefix + cur_line.rstrip())
cur_line = seg.lstrip()
if cur_line.strip() != '':
output.append(prefix + cur_line.strip())
def WrapCode(line, line_concat, output):
indent = len(line) - len(line.lstrip())
prefix = indent*' ' # Prefix of the current line
max_len = 80 - indent - len(line_concat) # Maximum length of the current line
new_prefix = prefix + 4*' ' # Prefix of a continuation line
new_max_len = max_len - 4 # Maximum length of a continuation line
# Prefers to wrap a line after a ',' or ';'.
segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
cur_line = '' # The current line without leading spaces.
for seg in segs:
# If the line is still too long, wrap at a space.
while cur_line == '' and len(seg.strip()) > max_len:
seg = seg.lstrip()
split_at = seg.rfind(' ', 0, max_len)
output.append(prefix + seg[:split_at].strip() + line_concat)
seg = seg[split_at + 1:]
prefix = new_prefix
max_len = new_max_len
if len((cur_line + seg).rstrip()) < max_len:
cur_line = (cur_line + seg).lstrip()
else:
output.append(prefix + cur_line.rstrip() + line_concat)
prefix = new_prefix
max_len = new_max_len
cur_line = seg.lstrip()
if cur_line.strip() != '':
output.append(prefix + cur_line.strip())
def WrapPreprocessorDirective(line, output):
WrapCode(line, ' \\', output)
def WrapPlainCode(line, output):
WrapCode(line, '', output)
def IsMultiLineIWYUPragma(line):
return re.search(r'/\* IWYU pragma: ', line)
def IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
re.match(r'^#include\s', line) or
# Don't break IWYU pragmas, either; that causes iwyu.py problems.
re.search(r'// IWYU pragma: ', line))
def WrapLongLine(line, output):
line = line.rstrip()
if len(line) <= 80:
output.append(line)
elif IsSingleLineComment(line):
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines,
# includes and IWYU pragmas.
output.append(line)
else:
WrapComment(line, output)
elif IsInPreprocessorDirective(output, line):
if IsHeaderGuardIncludeOrOneLineIWYUPragma(line):
# The style guide made an exception to allow long header guard lines,
# includes and IWYU pragmas.
output.append(line)
else:
WrapPreprocessorDirective(line, output)
elif IsMultiLineIWYUPragma(line):
output.append(line)
else:
WrapPlainCode(line, output)
def BeautifyCode(string):
lines = string.splitlines()
output = []
for line in lines:
WrapLongLine(line, output)
output2 = [line.rstrip() for line in output]
return '\n'.join(output2) + '\n'
def ConvertFromPumpSource(src_text):
"""Return the text generated from the given Pump source text."""
ast = ParseToAST(StripMetaComments(src_text))
output = Output()
RunCode(Env(), ast, output)
return BeautifyCode(output.string)
def main(argv):
if len(argv) == 1:
print __doc__
sys.exit(1)
file_path = argv[-1]
output_str = ConvertFromPumpSource(file(file_path, 'r').read())
if file_path.endswith('.pump'):
output_file_path = file_path[:-5]
else:
output_file_path = '-'
if output_file_path == '-':
print output_str,
else:
output_file = file(output_file_path, 'w')
output_file.write('// This file was GENERATED by command:\n')
output_file.write('// %s %s\n' %
(os.path.basename(__file__), os.path.basename(file_path)))
output_file.write('// DO NOT EDIT BY HAND!!!\n\n')
output_file.write(output_str)
output_file.close()
if __name__ == '__main__':
main(sys.argv)

View file

@ -0,0 +1,59 @@
# A Makefile for fusing Google Test and building a sample test against it.
#
# SYNOPSIS:
#
# make [all] - makes everything.
# make TARGET - makes the given target.
# make check - makes everything and runs the built sample test.
# make clean - removes all files generated by make.
# Points to the root of fused Google Test, relative to where this file is.
FUSED_GTEST_DIR = output
# Paths to the fused gtest files.
FUSED_GTEST_H = $(FUSED_GTEST_DIR)/gtest/gtest.h
FUSED_GTEST_ALL_CC = $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
# Where to find the sample test.
SAMPLE_DIR = ../../samples
# Where to find gtest_main.cc.
GTEST_MAIN_CC = ../../src/gtest_main.cc
# Flags passed to the preprocessor.
# We have no idea here whether pthreads is available in the system, so
# disable its use.
CPPFLAGS += -I$(FUSED_GTEST_DIR) -DGTEST_HAS_PTHREAD=0
# Flags passed to the C++ compiler.
CXXFLAGS += -g
all : sample1_unittest
check : all
./sample1_unittest
clean :
rm -rf $(FUSED_GTEST_DIR) sample1_unittest *.o
$(FUSED_GTEST_H) :
../fuse_gtest_files.py $(FUSED_GTEST_DIR)
$(FUSED_GTEST_ALL_CC) :
../fuse_gtest_files.py $(FUSED_GTEST_DIR)
gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GTEST_ALL_CC)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
gtest_main.o : $(FUSED_GTEST_H) $(GTEST_MAIN_CC)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_MAIN_CC)
sample1.o : $(SAMPLE_DIR)/sample1.cc $(SAMPLE_DIR)/sample1.h
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1.cc
sample1_unittest.o : $(SAMPLE_DIR)/sample1_unittest.cc \
$(SAMPLE_DIR)/sample1.h $(FUSED_GTEST_H)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1_unittest.cc
sample1_unittest : sample1.o sample1_unittest.o gtest-all.o gtest_main.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
#!/usr/bin/env python
#
# Copyright 2009, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""upload_gtest.py v0.1.0 -- uploads a Google Test patch for review.
This simple wrapper passes all command line flags and
--cc=googletestframework@googlegroups.com to upload.py.
USAGE: upload_gtest.py [options for upload.py]
"""
__author__ = 'wan@google.com (Zhanyong Wan)'
import os
import sys
CC_FLAG = '--cc='
GTEST_GROUP = 'googletestframework@googlegroups.com'
def main():
# Finds the path to upload.py, assuming it is in the same directory
# as this file.
my_dir = os.path.dirname(os.path.abspath(__file__))
upload_py_path = os.path.join(my_dir, 'upload.py')
# Adds Google Test discussion group to the cc line if it's not there
# already.
upload_py_argv = [upload_py_path]
found_cc_flag = False
for arg in sys.argv[1:]:
if arg.startswith(CC_FLAG):
found_cc_flag = True
cc_line = arg[len(CC_FLAG):]
cc_list = [addr for addr in cc_line.split(',') if addr]
if GTEST_GROUP not in cc_list:
cc_list.append(GTEST_GROUP)
upload_py_argv.append(CC_FLAG + ','.join(cc_list))
else:
upload_py_argv.append(arg)
if not found_cc_flag:
upload_py_argv.append(CC_FLAG + GTEST_GROUP)
# Invokes upload.py with the modified command line flags.
os.execv(upload_py_path, upload_py_argv)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,48 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: mheule@google.com (Markus Heule)
//
// Google C++ Testing Framework (Google Test)
//
// Sometimes it's desirable to build Google Test by compiling a single file.
// This file serves this purpose.
// This line ensures that gtest.h can be compiled on its own, even
// when it's fused.
#include "gtest/gtest.h"
// The following lines pull in the real gtest *.cc files.
#include "src/gtest.cc"
#include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc"
#include "src/gtest-port.cc"
#include "src/gtest-printers.cc"
#include "src/gtest-test-part.cc"
#include "src/gtest-typed-test.cc"

Some files were not shown because too many files have changed in this diff Show more