// Piece energy/capacity void test_piece_energy(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Piece - Energy/capacity ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("getting agent energy and resource capacities"); { Game g; Simple s(g, Position(0, 0), Game::STARTING_AGENT_ENERGY); Food f(g, Position(1, 1), Game::STARTING_RESOURCE_CAPACITY); Advantage a(g, Position(2, 2), Game::STARTING_RESOURCE_CAPACITY); Agent *agent = &s; Resource *r0 = &f, *r1 = &a; pass = (agent->getEnergy() == Game::STARTING_AGENT_ENERGY) && (r0->getCapacity() == Game::STARTING_RESOURCE_CAPACITY) && (r1->getCapacity() == Game::STARTING_RESOURCE_CAPACITY * Advantage::ADVANTAGE_MULT_FACTOR); ec.result(pass); } } }
// operator>>, operator<< (incl. exceptions) void test_point_IO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Stream IO ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("stream between two points"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 6.12 * i * i + 5.17 * i + 4.19; Point p2(50); std::stringstream iostr; iostr << std::setprecision(20) << p1; // Avoid truncation iostr >> p2; pass = true; for (int i = 0; i < 50; i++) pass = pass && (p2[i] == p1[i]); if (!pass) { std::cout << p1 << std::endl; std::cout << p2 << std::endl; } ec.result(pass); } } }
void test_piece_print(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Piece - Id-s, names, printing ---"); for (int run = 0; run < numRuns; run ++) { ec.DESC("piece id-s, names, and printing"); { Game g; // note: Game smoke test is needed first Position p0(0, 0); Simple s(g, p0, 10); Position p1(1, 0); Strategic t(g, p1, 20); Position p2(2, 2); Food f(g, p2, 5); Position p3(0, 2); Advantage a(g, p3, 3); std::stringstream ss; ss << s << ' ' << t << ' ' << f << ' ' << a; int id = 0; std::regex re("S[[:d:]]{1,}[ ]"); // ECMAScript, by default std::smatch m; std::string search_str(ss.str()); // convert string to lvalue // std::regex_search(ss.str(), m, re); std::regex_search(search_str, m, re); if (m.size() != 1) { // parse problem pass = false; } else { std::string matchStr(m[0]); std::regex r("[[:d:]]{1,}"); std::regex_search(matchStr, m, r); id = stoi(m[0]); pass = true; } std::stringstream compare; compare << 'S' << id << " T" << (id+1) << " F" << (id+2) << " D" << (id+3); pass = pass && (ss.str() == compare.str()); ec.result(pass); } } }
bool parseHash(const Dictionary& raw, blink::WebCryptoAlgorithm& hash, ErrorContext context, String& errorDetails) { Dictionary rawHash; if (!raw.get("hash", rawHash)) { errorDetails = context.toString("hash", "Missing or not a dictionary"); return false; } context.add("hash"); return parseAlgorithm(rawHash, Digest, hash, context, errorDetails); }
// operator>>, operator<< void test_cluster_IO(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Stream IO ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("read from a file"); { std::ifstream csv("points.csv"); Cluster c; if (csv.is_open()) { csv >> c; csv.close(); } pass = (c.getSize() == 4); ec.result(pass); } ec.DESC("read, write, and read again"); { std::ifstream csv("points.csv"); Cluster c; if (csv.is_open()) { csv >> c; csv.close(); } pass = (c.getSize() == 4); // add a point c.add(Point(5)); std::ofstream csv1("points1.csv", std::ofstream::out); csv1 << c; csv1.close(); std::ifstream csv2("points1.csv"); Cluster c2; if (csv2.is_open()) { csv2 >> c2; csv2.close(); }
// Defined by the WebCrypto spec as: // // typedef Uint8Array BigInteger; bool getBigInteger(const Dictionary& raw, const char* propertyName, RefPtr<Uint8Array>& array, const ErrorContext& context, String& errorDetails) { if (!getUint8Array(raw, propertyName, array, context, errorDetails)) return false; if (!array->byteLength()) { errorDetails = context.toString(propertyName, "BigInteger should not be empty"); return false; } if (!raw.get(propertyName, array) || !array) { errorDetails = context.toString(propertyName, "Missing or not a Uint8Array"); return false; } return true; }
bool getUint8Array(const Dictionary& raw, const char* propertyName, RefPtr<Uint8Array>& array, const ErrorContext& context, String& errorDetails) { if (!raw.get(propertyName, array) || !array) { errorDetails = context.toString(propertyName, "Missing or not a Uint8Array"); return false; } return true; }
// subscript (operator[]) void test_cluster_subscript(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Subscript ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("cluster with one point"); { Cluster c; Point p(10); p[5] = 3.14; c.add(p); Point p1 = c[0]; pass = p1[5] == 3.14; ec.result(pass); } ec.DESC("cluster with several point"); { Cluster c; for (int i = 0; i < 10; i ++) { Point p(10); p[5] = 3.14; c.add(p); } pass = true; for (int i = 0; i < 10; i ++) { Point p1 = c[i]; pass = pass && (p1[5] == 3.14); } ec.result(pass); } } }
// operator= void test_point_assignment(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Assign ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("simple assignment"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2 = p1; pass = true; for (int i = 0; i < 50; i++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } ec.DESC("chained assignment"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(50), p3(50), p4(50), p5(50); p2 = p3 = p4 = p5 = p1; pass = true; for (int i = 0; i < 50; i++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } } }
// Containment void test_cluster_contain(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Containment ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("cluster with one point"); { Point p(10); p[0] = p[2] = p[4] = p[8] = 6.705; Cluster c; c.add(p); pass = c.contains(p); ec.result(pass); } ec.DESC("cluster with several points"); { Point p(10); p[0] = p[2] = p[4] = p[8] = 6.705; Cluster c; for (int i = 0; i < 10; i ++) { Point pp(10); for (int j = 0; j < 10; j ++) { pp[i] = 3.4 + i * 2.1 + i * i; } c.add(pp); } c.add(p); pass = c.contains(p); ec.result(pass); } } }
// Defined by the WebCrypto spec as: // // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; // // FIXME: Currently only supports ArrayBufferView. bool getCryptoOperationData(const Dictionary& raw, const char* propertyName, RefPtr<ArrayBufferView>& buffer, const ErrorContext& context, String& errorDetails) { bool hasProperty; bool ok = getOptionalCryptoOperationData(raw, propertyName, hasProperty, buffer, context, errorDetails); if (!hasProperty) { errorDetails = context.toString(propertyName, "Missing required property"); return false; } return ok; }
// Copy constructor void test_point_copying(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Copy ---"); for (int run = 0; run < numRuns; run ++) { ec.DESC("simple copy"); { Point p1(50); for (int i = 0; i < 50; i ++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); pass = true; for (int i = 0; i < 50; i ++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } ec.DESC("pass and return by value"); { Point p1(50); for (int i = 0; i < 50; i ++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2 = point_in_and_out(p1); pass = true; for (int i = 0; i < 50; i ++) pass = pass && (p1[i] == p2[i]); ec.result(pass); } } }
// operator==, operator!= void test_point_equality(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Equal ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("compare equal"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); pass = (p2 == p1); ec.result(pass); } ec.DESC("ensure operator== is not a dummy"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); p2[1] = p2[1] + 1.0; pass = !(p2 == p1); ec.result(pass); } ec.DESC("compare not equal"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 44.56 * i * i + 23.45 * i + 12.34; Point p2(p1); p1[49] = p1[49] + 100.0; pass = (p2 != p1); ec.result(pass); } } }
// Copy constructor void test_cluster_copying(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Copy ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("simple copy"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2(c1); pass = (c1 == c2); ec.result(pass); } ec.DESC("chained copy"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2(c1), c3(c2), c4(c3); pass = (c1 == c4); ec.result(pass); } } }
// id void test_point_id(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Point ID ---"); for (int run = 0; run < numRuns; run ++) { ec.DESC("get a point's id"); { Point p(15); pass = (p.getId() >= 0); ec.result(pass); } ec.DESC("sequential id-s"); { Point **points = new Point*[100]; for (int i=0; i<100; i++) points[i] = new Point(15); pass = true; int firstId = points[0]->getId(); for (int i=0; i<100; i++) pass = pass && (points[i]->getId() == (firstId + i)); for (int i=0; i<100; i++) delete points[i]; delete [] points; ec.result(pass); } } }
bool getInteger(const Dictionary& raw, const char* propertyName, double& value, double minValue, double maxValue, const ErrorContext& context, String& errorDetails) { bool hasProperty; if (!getOptionalInteger(raw, propertyName, hasProperty, value, minValue, maxValue, context, errorDetails)) return false; if (!hasProperty) { errorDetails = context.toString(propertyName, "Missing required property"); return false; } return true; }
// Gets an integer according to WebIDL's [EnforceRange]. bool getOptionalInteger(const Dictionary& raw, const char* propertyName, bool& hasProperty, double& value, double minValue, double maxValue, const ErrorContext& context, String& errorDetails) { double number; bool ok = raw.get(propertyName, number, hasProperty); if (!hasProperty) return true; if (!ok || std::isnan(number)) { errorDetails = context.toString(propertyName, "Is not a number"); return false; } number = trunc(number); if (std::isinf(number) || number < minValue || number > maxValue) { errorDetails = context.toString(propertyName, "Outside of numeric range"); return false; } value = number; return true; }
// Defined by the WebCrypto spec as: // // dictionary AesCbcParams : Algorithm { // CryptoOperationData iv; // }; bool parseAesCbcParams(const Dictionary& raw, OwnPtr<blink::WebCryptoAlgorithmParams>& params, const ErrorContext& context, String& errorDetails) { RefPtr<ArrayBufferView> iv; if (!getCryptoOperationData(raw, "iv", iv, context, errorDetails)) return false; if (iv->byteLength() != 16) { errorDetails = context.toString("iv", "Must be 16 bytes"); return false; } params = adoptPtr(new blink::WebCryptoAesCbcParams(static_cast<unsigned char*>(iv->baseAddress()), iv->byteLength())); return true; }
// operator==, operator!= void test_cluster_equality(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Equal ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("check operator== is not a dummy"); { // The requirements don't provide for many other methods that // can be used for testing, so operator== is checked first Cluster c1, c2; c1.add(Point(100)); pass = !(c1 == c2); ec.result(pass); } ec.DESC("check inequality"); { // The requirements don't provide for many other methods that // can be used for testing, so operator== is checked first Cluster c1, c2; c1.add(Point(100)); pass = (c1 != c2); ec.result(pass); } } }
// Smoketest: constructor, copy constructor, destructor, resources void test_piece_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Unit - Smoketest ---"); ec.DESC("constructor, destructor for leaf classes from Piece hierarchy"); pass = true; for (int i = 0; i < 10; i++) { Game g; // note: Game smoke test is needed first Position p0(0, 0); Simple s(g, p0, 10); Position p1(1, 0); Strategic t(g, p1, 20); Position p2(2, 2); Food f(g, p2, 5); Position p3(0, 2); Advantage a(g, p3, 3); } ec.result(pass); }
// Defined by the WebCrypto spec as: // // typedef (ArrayBuffer or ArrayBufferView) CryptoOperationData; // // FIXME: Currently only supports ArrayBufferView. bool getOptionalCryptoOperationData(const Dictionary& raw, const char* propertyName, bool& hasProperty, RefPtr<ArrayBufferView>& buffer, const ErrorContext& context, String& errorDetails) { if (!raw.get(propertyName, buffer)) { hasProperty = false; return true; } hasProperty = true; if (!buffer) { errorDetails = context.toString(propertyName, "Not an ArrayBufferView"); return false; } return true; }
bool parseAlgorithmParams(const Dictionary& raw, blink::WebCryptoAlgorithmParamsType type, OwnPtr<blink::WebCryptoAlgorithmParams>& params, ErrorContext& context, String& errorDetails) { switch (type) { case blink::WebCryptoAlgorithmParamsTypeNone: return true; case blink::WebCryptoAlgorithmParamsTypeAesCbcParams: context.add("AesCbcParams"); return parseAesCbcParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeAesKeyGenParams: context.add("AesKeyGenParams"); return parseAesKeyGenParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeHmacImportParams: context.add("HmacImportParams"); return parseHmacImportParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeHmacKeyGenParams: context.add("HmacKeyGenParams"); return parseHmacKeyGenParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeRsaHashedKeyGenParams: context.add("RsaHashedKeyGenParams"); return parseRsaHashedKeyGenParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeRsaHashedImportParams: context.add("RsaHashedImportParams"); return parseRsaHashedImportParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeRsaKeyGenParams: context.add("RsaKeyGenParams"); return parseRsaKeyGenParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeAesCtrParams: context.add("AesCtrParams"); return parseAesCtrParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeAesGcmParams: context.add("AesGcmParams"); return parseAesGcmParams(raw, params, context, errorDetails); case blink::WebCryptoAlgorithmParamsTypeRsaOaepParams: // TODO notImplemented(); break; } ASSERT_NOT_REACHED(); return false; }
// Smoketest: constructor, copy constructor, destructor void test_point_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Point - Smoketest ---"); ec.DESC("constructor, dimensionality, destructor"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Point p(10); pass = (p.getDims() == 10); if (!pass) break; } ec.result(pass); ec.DESC("constructor, large size"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Point p(1000000); pass = (p.getDims() == 1000000); if (!pass) break; } ec.result(pass); ec.DESC("copy constructor"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Point p1(10); Point p2(p1); pass = (p1.getDims() == 10 && p2.getDims() == 10); if (!pass) break; } ec.result(pass); }
void empty(ErrorContext &ec) { ec.DESC("--- Empty matrices (0 by 0) ---"); // If this test fails, it means that getrows returned a non-zero value // when called on an "empty" (0x0) matrix created with the default // constructor. ec.DESC("default constructor and getrows"); // Construct an empty matrix using the default constructor. const Matrix a; // Make sure 'getrows' method returns zero for this matrix. ec.result(a.getrows() == 0); // Same as above, for getcols instead of getrows. ec.DESC("default constructor and getcols"); ec.result(a.getcols() == 0); // If this test fails, it means that getrows returned a non-zero value // when called on an "empty" (0x0) matrix created with the 2-argument // constructor. ec.DESC("two-argument constructor and getrows"); // Construct an empty matrix using the two-argument constructor. const Matrix b(0, 0); // Make sure 'getrows' method returns zero for this matrix. ec.result(b.getrows() == 0); // Same as above, for getcols instead of getrows. ec.DESC("two-argument constructor and getcols"); ec.result(b.getcols() == 0); }
// Smoketest: constructor, copy constructor, destructor void test_cluster_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Cluster - Smoketest ---"); ec.DESC("constructor, destructor"); pass = true; for (int i = 0; i < 10; i ++) { Cluster c; } ec.result(pass); ec.DESC("size getter - implement if you haven't"); pass = true; for (int i = 0; i < 10; i ++) { // Construct a Point // At the end of the block, destructor will be called Cluster c; pass = (c.getSize() == 0); if (!pass) break; } ec.result(pass); ec.DESC("copy constructor"); pass = true; for (int i = 0; i < 10; i ++) { Cluster c1, c2(c1); pass = (c1 == c2); if (!pass) break; } ec.result(pass); }
// Smoketest: constructor, copy constructor, destructor, number of pieces void test_game_smoketest(ErrorContext &ec) { bool pass; ec.DESC("--- Test - Game - Smoketest ---"); ec.DESC("constructor, empty game, default grid size, destructor"); pass = true; for (int i = 0; i < 10; i ++) { Game g; pass = (g.getWidth() == 3 && g.getHeight() == 3 && g.getNumPieces() == 0); } ec.result(pass); ec.DESC("constructor with dimensions"); pass = true; for (int i = 0; i < 10; i ++) { Game g(4, 5); pass = (g.getWidth() == 4 && g.getHeight() == 5 && g.getNumPieces() == 0); } ec.result(pass); ec.DESC("insufficient dimensions (exception generated)"); pass = true; for (int i = 0; i < 10; i ++) { try { Game g(Game::MIN_WIDTH-1, 5); pass = false; } catch (InsufficientDimensionsEx &ex) { std::cerr << "Exception generated: " << ex << std::endl; pass = (ex.getName() == "InsufficientDimensionsEx"); } } ec.result(pass); }
bool parseAlgorithm(const Dictionary& raw, AlgorithmOperation op, blink::WebCryptoAlgorithm& algorithm, ErrorContext context, String& errorDetails) { context.add("Algorithm"); if (!raw.isObject()) { errorDetails = context.toString("Not an object"); return false; } String algorithmName; if (!raw.get("name", algorithmName)) { errorDetails = context.toString("name", "Missing or not a string"); return false; } const AlgorithmInfo* info = AlgorithmRegistry::instance().lookupAlgorithmByName(algorithmName); if (!info) { errorDetails = context.toString("Unrecognized algorithm name"); return false; } context.add(info->algorithmName); if (info->paramsForOperation[op] == UnsupportedOp) { errorDetails = context.toString("Unsupported operation"); return false; } blink::WebCryptoAlgorithmParamsType paramsType = static_cast<blink::WebCryptoAlgorithmParamsType>(info->paramsForOperation[op]); OwnPtr<blink::WebCryptoAlgorithmParams> params; if (!parseAlgorithmParams(raw, paramsType, params, context, errorDetails)) return false; algorithm = blink::WebCryptoAlgorithm(info->algorithmId, params.release()); return true; }
//// operator= void test_cluster_assignment(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Assign ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("simple assignment"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2 = c1; pass = (c1 == c2); ec.result(pass); } ec.DESC("assignment causing deletion"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2; // add some other points c2.add(Point(10)); c2.add(Point(10)); c2.add(Point(10)); c2 = c1; pass = (c1 == c2); ec.result(pass); } ec.DESC("chained assignment"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); Cluster c2 = c1; Cluster c3 = c2; Cluster c4 = c3; pass = (c1 == c4); ec.result(pass); } } }
// distanceTo void test_point_distance(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Point - Distance ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("same point"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = 2.4 * i * i + 1.3 * i + 6.7; Point p2(p1); pass = (p1.distanceTo(p2) == 0); ec.result(pass); } ec.DESC("5 units away"); { Point p1(50); for (int i = 0; i < 50; i++) p1[i] = i; Point p2(p1); p2[1] += 5; pass = (p1.distanceTo(p2) == 5); if (!pass) std::cout << p1.distanceTo(p2) << " "; ec.result(pass); } // Integer sequence A180442 ec.DESC("distance 1612 from origin"); { Point p1(169); // 198 - 29 unsigned int start = 30; for (int i = 0; i < 169; i++) { p1[i] = start; start++; } Point origin(169); // relies on initialization to zeros pass = (p1.distanceTo(origin) == 1612); if (!pass) std::cout << p1.distanceTo(origin) << " "; ec.result(pass); } } }
// add, remove void test_cluster_addremove(ErrorContext &ec, unsigned int numRuns) { bool pass; // Run at least once!! assert(numRuns > 0); ec.DESC("--- Test - Cluster - Add/remove points ---"); for (int run = 0; run < numRuns; run++) { ec.DESC("add and check with size getter"); { Cluster c1; c1.add(Point(50)); c1.add(Point(50)); c1.add(Point(50)); pass = (c1.getSize() == 3); ec.result(pass); } // by default, points will get released here ec.DESC("add, remove, and check with size getter"); { Point p1(10), p2(10), p3(10); Cluster c1; c1.add(p1); c1.add(p2); c1.add(p3); c1.remove(p1); c1.remove(p2); c1.remove(p3); pass = (c1.getSize() == 0); if (!pass) { std::cout << std::endl; std::cout << c1 << std::endl; std::cout << std::endl; } ec.result(pass); } // by default, points will get released here ec.DESC("add, check with cluster equality, remove"); { Point p1(10), p2(10), p3(10); Cluster c1, c2; c1.add(p1); c1.add(p2); c1.add(p3); c2.add(p1); c2.add(p2); c2.add(p3); pass = (c1 == c2); // don't forget to remove the points from one // of the clusters to avoid the "double delete" c2.remove(p1); c2.remove(p2); c2.remove(p3); ec.result(pass); } ec.DESC("check point after add and remove"); { Point p1(10); for (int i = 0; i < 10; i++) p1[i] = 5.4 * i * i + 3.4 * i + 1.6; Cluster c1; c1.add(p1); Point p2 = c1.remove(p1); pass = (p1 == p2); ec.result(pass); } } }