1  /**
     2   * Copyright the original author or authors.
     3   * 
     4   * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   * 
     8   *      http://www.mozilla.org/MPL/MPL-1.1.html
     9   * 
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  import org.as2lib.core.BasicClass;
    18  import org.as2lib.util.ObjectUtil;
    19  import org.as2lib.test.mock.ArgumentsMatcher;
    20  import org.as2lib.test.mock.ArgumentMatcher;
    21  
    22  /**
    23   * {@code TypeArgumentsMatcher} matches the actual arguments agains a list of types.
    24   * 
    25   * @author Simon Wacker
    26   */
    27  class org.as2lib.test.mock.support.TypeArgumentsMatcher extends BasicClass implements ArgumentsMatcher {
    28  	
    29  	/** The expected types. */
    30  	private var expectedTypes:Array;
    31  	
    32  	/**
    33  	 * Constructs a new {@code TypeArgumentsMatcher} instance.
    34  	 *
    35  	 * <p>If a type in the {@code expectedType} array is {@code null} or
    36  	 * {@code undefined} the expected and actual argument will be compared.
    37  	 * 
    38  	 * <p>If an element in the {@code expectedType} array is an instance of type
    39  	 * {@link ArgumentMatcher}, this argument matcher will be used to check whether
    40  	 * the actual argument is correct.
    41  	 * 
    42  	 * @param expectedTypes the expected types of the arguments
    43  	 */
    44  	public function TypeArgumentsMatcher(expectedTypes:Array) {
    45  		this.expectedTypes = expectedTypes;
    46  	}
    47  	
    48  	/**
    49  	 * Compares the actual arguments only by type against the expected types given on
    50  	 * contruction.
    51  	 *
    52  	 * <p>If a type of the expected types is {@code null} or {@code undefined} the
    53  	 * expected and actual argument will be compared directly with the strict equals
    54  	 * operator.
    55  	 *
    56  	 * <p>{@code false} will be returned if:
    57  	 * <ul>
    58  	 *   <li>The lengths of the expected and actual arguments differ.</li>
    59  	 *   <li>The lengths of the expected types and the actual arguments differ.</li>
    60  	 *   <li>Any actual argument is not of the expected type.</li>
    61  	 * </ul>
    62  	 *
    63  	 * @param expectedArgumens the expected arguments
    64  	 * @param actualArguments the actual arguments
    65  	 */
    66  	public function matchArguments(expectedArguments:Array, actualArguments:Array):Boolean {
    67  		if (expectedArguments.length != actualArguments.length) return false;
    68  		if (actualArguments.length != expectedTypes.length) return false;
    69  		for (var i:Number = 0; i < expectedArguments.length; i++) {
    70  			if (expectedTypes[i] == null) {
    71  				if (expectedArguments[i] !== actualArguments[i]) {
    72  					return false;
    73  				}
    74  			} else if (expectedTypes[i] instanceof ArgumentMatcher) {
    75  				if (!ArgumentMatcher(expectedTypes[i]).matchArgument(actualArguments[i])) {
    76  					return false;
    77  				}
    78  			} else {
    79  				if (!ObjectUtil.typesMatch(actualArguments[i], expectedTypes[i])) {
    80  					return false;
    81  				}
    82  			}
    83  		}
    84  		return true;
    85  	}
    86  	
    87  }