/** * Catroid: An on-device graphical programming language for Android devices * Copyright (C) 2010-2011 The Catroid Team * (<http://code.google.com/p/catroid/wiki/Credits>) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * An additional term exception under section 7 of the GNU Affero * General Public License, version 3, is available at * http://www.catroid.org/catroid_license_additional_term * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package at.tugraz.ist.catroid.test.content.brick; import android.test.FlakyTest; import android.test.InstrumentationTestCase; import at.tugraz.ist.catroid.content.Sprite; import at.tugraz.ist.catroid.content.StartScript; import at.tugraz.ist.catroid.content.bricks.ChangeYByBrick; import at.tugraz.ist.catroid.content.bricks.LoopBeginBrick; import at.tugraz.ist.catroid.content.bricks.LoopEndBrick; import at.tugraz.ist.catroid.content.bricks.RepeatBrick; import at.tugraz.ist.catroid.test.utils.TestUtils; public class RepeatBrickTest extends InstrumentationTestCase { private Sprite testSprite; private StartScript testScript; private static final int REPEAT_TIMES = 10; private LoopEndBrick loopEndBrick; private LoopBeginBrick repeatBrick; @Override protected void setUp() throws Exception { testSprite = new Sprite("testSprite"); } public void testRepeatBrick() throws InterruptedException { testSprite.removeAllScripts(); testScript = new StartScript(testSprite); repeatBrick = new RepeatBrick(testSprite, REPEAT_TIMES); loopEndBrick = new LoopEndBrick(testSprite, repeatBrick); repeatBrick.setLoopEndBrick(loopEndBrick); final int deltaY = -10; final int expectedDelay = (Integer) TestUtils.getPrivateField("LOOP_DELAY", loopEndBrick, false); testScript.addBrick(repeatBrick); testScript.addBrick(new ChangeYByBrick(testSprite, deltaY)); testScript.addBrick(loopEndBrick); testSprite.addScript(testScript); testSprite.startStartScripts(); /* * Let's wait even longer than necessary, then check if we only executed N times, not N+1 times * http://code.google.com/p/catroid/issues/detail?id=24 */ Thread.sleep(expectedDelay * REPEAT_TIMES * 2); assertEquals("Executed the wrong number of times!", REPEAT_TIMES * deltaY, (int) testSprite.costume.getYPosition()); } @FlakyTest(tolerance = 3) public void testLoopDelay() throws InterruptedException { testSprite.removeAllScripts(); testScript = new StartScript(testSprite); repeatBrick = new RepeatBrick(testSprite, REPEAT_TIMES); loopEndBrick = new LoopEndBrick(testSprite, repeatBrick); repeatBrick.setLoopEndBrick(loopEndBrick); final int deltaY = -10; final int expectedDelay = (Integer) TestUtils.getPrivateField("LOOP_DELAY", loopEndBrick, false); testScript.addBrick(repeatBrick); testScript.addBrick(new ChangeYByBrick(testSprite, deltaY)); testScript.addBrick(loopEndBrick); testScript.addBrick(new ChangeYByBrick(testSprite, 150)); testSprite.addScript(testScript); final long startTime = System.currentTimeMillis(); testSprite.startStartScripts(); Thread.sleep(expectedDelay * REPEAT_TIMES); assertEquals("Loop delay did not work!", REPEAT_TIMES * deltaY, (int) testSprite.costume.getYPosition()); /* * This is only to document that a delay of 20ms is by contract. See Issue 28 in Google Code * http://code.google.com/p/catroid/issues/detail?id=28 */ final long delayByContract = 20; final long endTime = System.currentTimeMillis(); assertEquals("Loop delay did was not 20ms!", delayByContract * REPEAT_TIMES, endTime - startTime, 15); } public void testNegativeRepeats() throws InterruptedException { testSprite.removeAllScripts(); testScript = new StartScript(testSprite); repeatBrick = new RepeatBrick(testSprite, -1); loopEndBrick = new LoopEndBrick(testSprite, repeatBrick); repeatBrick.setLoopEndBrick(loopEndBrick); final int decoyDeltaY = -150; final int expectedDeltaY = 150; final int expectedDelay = (Integer) TestUtils.getPrivateField("LOOP_DELAY", loopEndBrick, false); testScript.addBrick(repeatBrick); testScript.addBrick(new ChangeYByBrick(testSprite, decoyDeltaY)); testScript.addBrick(loopEndBrick); testScript.addBrick(new ChangeYByBrick(testSprite, expectedDeltaY)); testSprite.addScript(testScript); testSprite.startStartScripts(); /* * Waiting less than what a loop delay would be! Loop should not execute and there should be no delay * http://code.google.com/p/catroid/issues/detail?id=24#c9 */ Thread.sleep(expectedDelay / 2); assertEquals("Loop was executed although repeats were less than zero!", expectedDeltaY, (int) testSprite.costume.getYPosition()); } public void testZeroRepeats() throws InterruptedException { testSprite.removeAllScripts(); testScript = new StartScript(testSprite); repeatBrick = new RepeatBrick(testSprite, 0); loopEndBrick = new LoopEndBrick(testSprite, repeatBrick); repeatBrick.setLoopEndBrick(loopEndBrick); final int decoyDeltaY = -150; final int expectedDeltaY = 150; final int expectedDelay = (Integer) TestUtils.getPrivateField("LOOP_DELAY", loopEndBrick, false); testScript.addBrick(repeatBrick); testScript.addBrick(new ChangeYByBrick(testSprite, decoyDeltaY)); testScript.addBrick(loopEndBrick); testScript.addBrick(new ChangeYByBrick(testSprite, expectedDeltaY)); testSprite.addScript(testScript); testSprite.startStartScripts(); /* * Waiting less than what a loop delay would be! Loop should not execute and there should be no delay * http://code.google.com/p/catroid/issues/detail?id=24#c9 */ Thread.sleep(expectedDelay / 2); assertEquals("Loop was executed although repeats were set to zero!", expectedDeltaY, (int) testSprite.costume.getYPosition()); } }