// 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);
        }
    }
}
Example #4
0
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();
            }
Example #6
0
// 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;
}
Example #7
0
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);
        }
    }
}
Example #11
0
// 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);
        }
    }
}
Example #16
0
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;
}
Example #17
0
// 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;
}
Example #18
0
// 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);
        }
    }
}
Example #20
0
// 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);
}
Example #21
0
// 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;
}
Example #22
0
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);
}
Example #24
0
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);
}
Example #26
0
// 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);
}
Example #27
0
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);
        }
    }
}