/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.jpql;

public class JPQLUnitTestSuite extends org.eclipse.persistence.testing.framework.TestSuite {
    public JPQLUnitTestSuite() {
        setDescription("The unit tests for EJBQL");
    }

    @Override
    public void addTests() {
        //SELECT tests
        //invalid EJBQL-cannot change reference class
        //addTest(new SimpleSelectPhoneNumber());
        //addTest(new SimpleSelectPhoneNumberWithEmployee());
        //addTest(new SimpleSelectPhoneNumberWithEmployeeWithExplicitJoin());
        //addTest(new SimpleSelectPhoneNumberWithEmployeeWithFirstNameFirst());
        //addTest(new SimpleSelectPhoneNumberFullyQualifiedInSELECT());
        //SELECT attribute tests
        addTest(new SimpleSelectPhoneNumberAreaCode());
        addTest(new SimpleSelectPhoneNumberAreaCodeWithEmployee());
        addTest(new SimpleSelectPhoneNumberNumberWithEmployeeWithExplicitJoin());
        addTest(new SimpleSelectPhoneNumberNumberWithEmployeeWithFirstNameFirst());

        //invalid EBJQL
        //addTest(new SimpleSelectPhoneNumberAreaCodeFullyQualifiedInSELECT());
    }
}
