/*
 * Copyright (c) 2005, 2018 IBM Corporation, CEA, and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   IBM - initial API and implementation
 *   Kenn Hussey (CEA) - 327039, 351774, 418466
 *   Kenn Hussey - 535301
 *
 */
package org.eclipse.uml2.uml.tests;

import junit.textui.TestRunner;

import org.eclipse.uml2.uml.ReduceAction;
import org.eclipse.uml2.uml.UMLFactory;

/**
 * <!-- begin-user-doc -->
 * A test case for the model object '<em><b>Reduce Action</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following operations are tested:
 * <ul>
 *   <li>{@link org.eclipse.uml2.uml.ReduceAction#validateReducerInputsOutput(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Reducer Inputs Output</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.ReduceAction#validateInputTypeIsCollection(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Input Type Is Collection</em>}</li>
 *   <li>{@link org.eclipse.uml2.uml.ReduceAction#validateOutputTypesAreCompatible(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Output Types Are Compatible</em>}</li>
 * </ul>
 * </p>
 * @generated
 */
public class ReduceActionTest
		extends ActionTest {

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public static void main(String[] args) {
		TestRunner.run(ReduceActionTest.class);
	}

	/**
	 * Constructs a new Reduce Action test case with the given name.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ReduceActionTest(String name) {
		super(name);
	}

	/**
	 * Returns the fixture for this Reduce Action test case.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected ReduceAction getFixture() {
		return (ReduceAction) fixture;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see junit.framework.TestCase#setUp()
	 * @generated
	 */
	@Override
	protected void setUp()
			throws Exception {
		setFixture(UMLFactory.eINSTANCE.createReduceAction());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see junit.framework.TestCase#tearDown()
	 * @generated
	 */
	@Override
	protected void tearDown()
			throws Exception {
		setFixture(null);
	}

	/**
	 * Tests the '{@link org.eclipse.uml2.uml.ReduceAction#validateInputTypeIsCollection(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Input Type Is Collection</em>}' operation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see org.eclipse.uml2.uml.ReduceAction#validateInputTypeIsCollection(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map)
	 * @generated
	 */
	public void testValidateInputTypeIsCollection__DiagnosticChain_Map() {
		// TODO: implement this feature getter test method
		// Ensure that you remove @generated or mark it @generated NOT
	}

	/**
	 * Tests the '{@link org.eclipse.uml2.uml.ReduceAction#validateOutputTypesAreCompatible(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Output Types Are Compatible</em>}' operation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see org.eclipse.uml2.uml.ReduceAction#validateOutputTypesAreCompatible(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map)
	 * @generated
	 */
	public void testValidateOutputTypesAreCompatible__DiagnosticChain_Map() {
		// TODO: implement this feature getter test method
		// Ensure that you remove @generated or mark it @generated NOT
	}

	/**
	 * Tests the '{@link org.eclipse.uml2.uml.ReduceAction#validateReducerInputsOutput(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map) <em>Validate Reducer Inputs Output</em>}' operation.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see org.eclipse.uml2.uml.ReduceAction#validateReducerInputsOutput(org.eclipse.emf.common.util.DiagnosticChain, java.util.Map)
	 * @generated
	 */
	public void testValidateReducerInputsOutput__DiagnosticChain_Map() {
		// TODO: implement this feature getter test method
		// Ensure that you remove @generated or mark it @generated NOT
	}

} //ReduceActionTest
