| <?xml version="1.0" encoding="utf-8"?> |
| <!-- |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| --> |
| <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" |
| xmlns:s="library://ns.adobe.com/flex/spark" |
| xmlns:mx="library://ns.adobe.com/flex/mx" |
| preinitialize="preInit()"> |
| <!-- |
| This is the base class for all of the monitors. The idea behind monitors is to provide plugable testing: |
| Essentially, monitors do the actual operations of detecting whether or not something is behaving based on a pre- |
| defined criteria (e.g. symmetric change) without actually interfacing with the thing being tested directly. This |
| enables them to be swapped in at runtime by Mustella without needing to create seperate files for each test. |
| --> |
| <fx:Script> |
| <![CDATA[ |
| import mx.collections.ArrayList; |
| import mx.core.IFlexDisplayObject; |
| import mx.events.CloseEvent; |
| import mx.events.EffectEvent; |
| import mx.events.FlexEvent; |
| |
| protected var timer:Timer; |
| public var start:int; |
| public var stop:int; |
| public var end:int; |
| public var repeat:int; |
| |
| [Bindable] |
| public var initialValues:Vector.<Number>; |
| protected var initialUpdates:Vector.<Number>; |
| |
| [Bindable] |
| public var returnValues:Vector.<Number>; |
| protected var returnUpdates:Vector.<Number>; |
| |
| [Bindable] |
| public var isReturn:Boolean; |
| |
| [Bindable] |
| public var valueFunction:Function; |
| [Bindable] |
| public var target:Object; |
| [Bindable] |
| public var passed:Boolean; |
| [Bindable] |
| public var error:String; |
| |
| public function preInit():void{ |
| timer = new Timer(20); |
| initialValues = new Vector.<Number>(); |
| initialUpdates = new Vector.<Number>(); |
| |
| returnValues = new Vector.<Number>(); |
| returnUpdates = new Vector.<Number>(); |
| |
| isReturn = false; |
| passed = true; |
| } |
| |
| public function effectStart(event:EffectEvent):void{ |
| timer.start(); |
| start = timer.currentCount * 20; |
| } |
| |
| public function effectStop(event:EffectEvent):void{ |
| stop = timer.currentCount * 20; |
| timer.stop(); |
| } |
| |
| public function effectUpdate(event:EffectEvent):void{ |
| if(isReturn){ |
| returnValues.push(valueFunction.call(target) as Number); |
| returnUpdates.push((timer.currentCount * 20) - start); |
| }else{ |
| initialValues.push(valueFunction.call(target) as Number); |
| initialUpdates.push((timer.currentCount * 20) - start); |
| } |
| } |
| |
| public function effectEnd(event:EffectEvent):void{ |
| end = timer.currentCount * 20; |
| timer.stop(); |
| } |
| |
| public function effectRepeat(event:EffectEvent):void{ |
| repeat++; |
| } |
| |
| public function resetMonitors():void { |
| start = 0; |
| stop = 0; |
| repeat = 0; |
| end = 0; |
| } |
| |
| protected function computeDeltas(vector:Vector.<Number>):Vector.<Number> { |
| var diff:Vector.<Number> = new Vector.<Number>(); |
| var prev:Number = Number.NaN; |
| for each(var n:Number in vector){ |
| if(!isNaN(prev)){ |
| diff.push(Math.abs(n - prev)); |
| } |
| prev = n; |
| } |
| |
| return diff; |
| } |
| |
| protected function computeRates(values:Vector.<Number>,times:Vector.<Number>):Vector.<Number> { |
| var rates:Vector.<Number> = new Vector.<Number>(); |
| var deltaV:Vector.<Number> = computeDeltas(values); |
| var deltaT:Vector.<Number> = computeDeltas(times); |
| |
| for(var i:int = 0; i < deltaV.length; i++){ |
| var deltaVNum:Number = deltaV.pop(); |
| var deltaTNum:Number = deltaT.pop(); |
| |
| if(deltaTNum != 0){ |
| if(deltaVNum == 0){ |
| rates.push(0); |
| }else{ |
| rates.push(deltaVNum / deltaTNum); |
| } |
| } |
| } |
| |
| return rates.reverse(); |
| } |
| |
| public function check():void { |
| if(Math.abs(initialValues[0] - initialValues[initialValues.length - 1]) < 0.5){ |
| passed = false; |
| error = "Initial value is not substantially different from end value in the first transition. " + initialValues[0] + " vs. " + initialValues[initialValues.length - 1]; |
| trace("Monitor: " + error); |
| } |
| } |
| ]]> |
| </fx:Script> |
| <s:Label id="readout" text="Passed: {passed}"/> |
| </s:Group> |