/* * Catroid: An on-device visual programming system for Android devices * Copyright (C) 2010-2016 The Catrobat Team * (<http://developer.catrobat.org/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://developer.catrobat.org/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 org.catrobat.catroid.test.content.bricks; import android.test.AndroidTestCase; import android.util.Log; import com.badlogic.gdx.scenes.scene2d.actions.SequenceAction; import org.catrobat.catroid.ProjectManager; import org.catrobat.catroid.content.Project; import org.catrobat.catroid.content.Script; import org.catrobat.catroid.content.SingleSprite; import org.catrobat.catroid.content.Sprite; import org.catrobat.catroid.content.StartScript; import org.catrobat.catroid.content.bricks.Brick; import org.catrobat.catroid.content.bricks.ChangeXByNBrick; import org.catrobat.catroid.content.bricks.LegoNxtMotorStopBrick; import org.catrobat.catroid.content.bricks.LegoNxtMotorStopBrick.Motor; import org.catrobat.catroid.content.bricks.UserBrick; import org.catrobat.catroid.content.bricks.UserScriptDefinitionBrick; import org.catrobat.catroid.formulaeditor.Formula; import org.catrobat.catroid.formulaeditor.FormulaElement; import org.catrobat.catroid.formulaeditor.FormulaElement.ElementType; import org.catrobat.catroid.formulaeditor.InterpretationException; import org.catrobat.catroid.test.utils.Reflection; import org.catrobat.catroid.test.utils.TestUtils; import java.util.ArrayList; import java.util.List; public class UserBrickTest extends AndroidTestCase { private static final String TAG = UserBrickTest.class.getSimpleName(); private Sprite sprite; @Override protected void setUp() throws Exception { super.setUp(); sprite = new SingleSprite("testSprite"); Project project = new Project(null, "testProject"); project.getDefaultScene().addSprite(sprite); ProjectManager.getInstance().setProject(project); ProjectManager.getInstance().setCurrentSprite(sprite); } @Override protected void tearDown() throws Exception { ProjectManager.getInstance().setProject(null); ProjectManager.getInstance().setCurrentSprite(null); super.tearDown(); } public void testSpriteHasOneUserBrickAfterAddingAUserBrick() { UserBrick brick = new UserBrick(new UserScriptDefinitionBrick()); brick.getDefinitionBrick().addUIText("test0"); brick.getDefinitionBrick().addUILocalizedVariable("test1"); Script userScript = TestUtils.addUserBrickToSpriteAndGetUserScript(brick, sprite); userScript.addBrick(new ChangeXByNBrick(1)); ArrayList<?> array = (ArrayList<?>) Reflection.getPrivateFieldOfBaseClass(sprite, "userBricks"); assertTrue("the sprite should have one user brick after we added a user brick to it, has " + array.size(), array.size() == 1); } public void testSpriteMovedCorrectly() { int moveValue = 0; UserBrick brick = new UserBrick(new UserScriptDefinitionBrick()); brick.getDefinitionBrick().addUIText("test0"); brick.getDefinitionBrick().addUILocalizedVariable("test1"); brick.updateUserBrickParametersAndVariables(); Script userScript = TestUtils.addUserBrickToSpriteAndGetUserScript(brick, sprite); userScript.addBrick(new ChangeXByNBrick(moveValue)); SequenceAction sequence = new SequenceAction(); brick.addActionToSequence(sprite, sequence); float x = sprite.look.getXInUserInterfaceDimensionUnit(); float y = sprite.look.getYInUserInterfaceDimensionUnit(); assertEquals("Unexpected initial sprite x position: " + x, 0f, x); assertEquals("Unexpected initial sprite y position: " + y, 0f, y); sequence.act(1f); assertEquals("Unexpected initial sprite x position: ", (float) moveValue, sprite.look.getXInUserInterfaceDimensionUnit()); assertEquals("Unexpected initial sprite y position: ", 0f, sprite.look.getYInUserInterfaceDimensionUnit()); } public void testSpriteMovedCorrectlyWithNestedBricks() { Integer moveValue = 0; UserBrick outerBrick = new UserBrick(new UserScriptDefinitionBrick()); outerBrick.getDefinitionBrick().addUIText("test2"); outerBrick.getDefinitionBrick().addUILocalizedVariable("outerBrickVariable"); outerBrick.updateUserBrickParametersAndVariables(); UserBrick innerBrick = new UserBrick(new UserScriptDefinitionBrick()); innerBrick.getDefinitionBrick().addUIText("test0"); innerBrick.getDefinitionBrick().addUILocalizedVariable("innerBrickVariable"); Script innerScript = TestUtils.addUserBrickToSpriteAndGetUserScript(innerBrick, sprite); Formula innerFormula = new Formula(new FormulaElement(ElementType.USER_VARIABLE, "innerBrickVariable", null)); innerScript.addBrick(new ChangeXByNBrick(innerFormula)); innerBrick.updateUserBrickParametersAndVariables(); Script outerScript = TestUtils.addUserBrickToSpriteAndGetUserScript(outerBrick, sprite); UserBrick innerBrickCopyInOuterScript = innerBrick.copyBrickForSprite(sprite); outerScript.addBrick(innerBrickCopyInOuterScript); List<Formula> formulaList = innerBrickCopyInOuterScript.getFormulas(); assertEquals("formulaList.size() after innerBrick.updateUserBrickParameters()" + formulaList.size(), 1, formulaList.size()); for (Formula formula : formulaList) { formula.setRoot(new FormulaElement(ElementType.USER_VARIABLE, "outerBrickVariable", null)); } StartScript startScript = new StartScript(); sprite.addScript(startScript); UserBrick outerBrickCopy = outerBrick.copyBrickForSprite(sprite); startScript.addBrick(outerBrickCopy); formulaList = outerBrickCopy.getFormulas(); assertEquals("formulaList.size() after outerBrick.updateUserBrickParameters()" + formulaList.size(), 1, formulaList.size()); for (Formula formula : formulaList) { formula.setRoot(new FormulaElement(ElementType.NUMBER, moveValue.toString(), null)); try { assertEquals("outerBrick.formula.interpretDouble: ", (float) moveValue, formula.interpretFloat(sprite)); } catch (InterpretationException e) { Log.e(TAG, "Interpretation Error", e); } } runAndCheckSpritePosition(startScript, moveValue, 0); } public void testGetRequiredResources() { UserBrick brick = new UserBrick(new UserScriptDefinitionBrick()); assertEquals("brick.getRequiredResources(): ", UserBrick.NO_RESOURCES, brick.getRequiredResources()); Script userScript = TestUtils.addUserBrickToSpriteAndGetUserScript(brick, sprite); LegoNxtMotorStopBrick legoBrick = new LegoNxtMotorStopBrick(Motor.MOTOR_A); userScript.addBrick(legoBrick); assertNotSame("legoBrick.getRequiredResources(): ", UserBrick.NO_RESOURCES, legoBrick.getRequiredResources()); assertEquals("brick.getRequiredResources(): ", legoBrick.getRequiredResources(), brick.getRequiredResources()); } public void testDeleteBrick() { UserBrick outerBrick = new UserBrick(new UserScriptDefinitionBrick()); outerBrick.getDefinitionBrick().addUIText("test2"); outerBrick.getDefinitionBrick().addUILocalizedVariable("outerBrickVariable"); outerBrick.updateUserBrickParametersAndVariables(); UserBrick innerBrick = new UserBrick(new UserScriptDefinitionBrick()); innerBrick.getDefinitionBrick().addUIText("test0"); innerBrick.getDefinitionBrick().addUILocalizedVariable("innerBrickVariable"); Script innerScript = TestUtils.addUserBrickToSpriteAndGetUserScript(innerBrick, sprite); Formula innerFormula = new Formula(new FormulaElement(ElementType.USER_VARIABLE, "innerBrickVariable", null)); innerScript.addBrick(new ChangeXByNBrick(innerFormula)); innerBrick.updateUserBrickParametersAndVariables(); Script outerScript = TestUtils.addUserBrickToSpriteAndGetUserScript(outerBrick, sprite); Brick innerBrickCopyInOuterScript = innerBrick.copyBrickForSprite(sprite); outerScript.addBrick(innerBrickCopyInOuterScript); StartScript startScript = new StartScript(); sprite.addScript(startScript); Brick innerBrickCopy = innerBrick.copyBrickForSprite(sprite); startScript.addBrick(innerBrickCopy); Brick outerBrickCopy = outerBrick.copyBrickForSprite(sprite); startScript.addBrick(outerBrickCopy); assertEquals("Start script has wrong number of bricks before deleting.", 2, startScript.getBrickList().size()); assertEquals("Start script has wrong brick before deleting.", innerBrickCopy, startScript.getBrick(0)); assertEquals("outerScript has wrong number of bricks before deleting.", 1, outerScript.getBrickList().size()); assertEquals("outerScript has wrong brick before deleting.", innerBrickCopyInOuterScript, outerScript.getBrick(0)); sprite.removeUserBrick(innerBrick); assertEquals("Start script user brick was also deleted", 2, startScript.getBrickList().size()); assertEquals("Start script has wrong brick after deleting.", innerBrickCopy, startScript.getBrick(0)); assertEquals("Start script has wrong brick after deleting.", outerBrickCopy, startScript.getBrick(1)); assertEquals("outerScript has wrong number of bricks after deleting.", 1, outerScript.getBrickList().size()); } public void testBrickCloneWithFormula() { UserBrick brick = new UserBrick(new UserScriptDefinitionBrick()); brick.getDefinitionBrick().addUIText("test0"); brick.getDefinitionBrick().addUILocalizedVariable("test1"); UserBrick cloneBrick = brick.copyBrickForSprite(sprite); UserScriptDefinitionBrick definition = (UserScriptDefinitionBrick) Reflection.getPrivateField(brick, "definitionBrick"); UserScriptDefinitionBrick clonedDef = (UserScriptDefinitionBrick) Reflection.getPrivateField(cloneBrick, "definitionBrick"); assertFalse("The cloned brick has the same UserScriptDefinitionBrick instance as the original brick", definition == clonedDef); ArrayList<?> componentArray = (ArrayList<?>) Reflection.getPrivateField(brick, "userBrickParameters"); ArrayList<?> clonedComponentArray = (ArrayList<?>) Reflection.getPrivateField(cloneBrick, "userBrickParameters"); assertTrue("The cloned brick has a different userBrickElements than the original brick", componentArray != clonedComponentArray); } private void runAndCheckSpritePosition(Script startScript, Integer expectedX, Integer expectedY) { SequenceAction sequence = new SequenceAction(); startScript.run(sprite, sequence); float x = sprite.look.getXInUserInterfaceDimensionUnit(); float y = sprite.look.getYInUserInterfaceDimensionUnit(); assertEquals("Unexpected initial sprite x position: ", 0f, x); assertEquals("Unexpected initial sprite y position: ", 0f, y); sequence.act(1f); x = sprite.look.getXInUserInterfaceDimensionUnit(); y = sprite.look.getYInUserInterfaceDimensionUnit(); assertEquals("Unexpected sprite x position: ", (float) expectedX, x); assertEquals("Unexpected sprite y position: ", (float) expectedY, y); } }