/*
* 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.utils;
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import android.util.SparseArray;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import junit.framework.Assert;
import org.catrobat.catroid.ProjectManager;
import org.catrobat.catroid.R;
import org.catrobat.catroid.common.Constants;
import org.catrobat.catroid.common.FileChecksumContainer;
import org.catrobat.catroid.common.defaultprojectcreators.DefaultProjectCreatorDrone;
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.AddItemToUserListBrick;
import org.catrobat.catroid.content.bricks.Brick;
import org.catrobat.catroid.content.bricks.ComeToFrontBrick;
import org.catrobat.catroid.content.bricks.HideBrick;
import org.catrobat.catroid.content.bricks.IfLogicBeginBrick;
import org.catrobat.catroid.content.bricks.IfLogicElseBrick;
import org.catrobat.catroid.content.bricks.IfLogicEndBrick;
import org.catrobat.catroid.content.bricks.SetVariableBrick;
import org.catrobat.catroid.content.bricks.ShowBrick;
import org.catrobat.catroid.content.bricks.UserBrick;
import org.catrobat.catroid.content.bricks.UserScriptDefinitionBrick;
import org.catrobat.catroid.exceptions.ProjectException;
import org.catrobat.catroid.formulaeditor.Formula;
import org.catrobat.catroid.formulaeditor.FormulaElement;
import org.catrobat.catroid.formulaeditor.UserList;
import org.catrobat.catroid.formulaeditor.UserVariable;
import org.catrobat.catroid.io.StorageHandler;
import org.catrobat.catroid.utils.NotificationData;
import org.catrobat.catroid.utils.StatusBarNotificationManager;
import org.catrobat.catroid.utils.UtilFile;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public final class TestUtils {
public static final int TYPE_IMAGE_FILE = 0;
public static final int TYPE_SOUND_FILE = 1;
public static final String DEFAULT_TEST_PROJECT_NAME = "testProject";
public static final String CORRUPT_PROJECT_NAME = "copiedProject";
public static final String EMPTY_PROJECT = "emptyProject";
private static final String TAG = TestUtils.class.getSimpleName();
public static final double DELTA = 0.00001;
// Suppress default constructor for noninstantiability
private TestUtils() {
throw new AssertionError();
}
/**
* saves a file into the project folder
* if project == null or "" file will be saved into Catroid folder
*
* @param project Folder where the file will be saved, this folder should exist
* @param name Name of the file
* @param fileID the id of the file --> needs the right context
* @param context
* @param type type of the file: 0 = imagefile, 1 = soundfile
* @return the file
* @throws IOException
*/
public static File saveFileToProject(String project, String scene, String name, int fileID, Context context, int type)
throws IOException {
String filePath;
if (project == null || project.equalsIgnoreCase("")) {
filePath = Constants.DEFAULT_ROOT + "/" + name;
} else {
switch (type) {
case TYPE_IMAGE_FILE:
filePath = Constants.DEFAULT_ROOT + "/" + project + "/" + scene + "/" + Constants.IMAGE_DIRECTORY + "/" + name;
break;
case TYPE_SOUND_FILE:
filePath = Constants.DEFAULT_ROOT + "/" + project + "/" + scene + "/" + Constants.SOUND_DIRECTORY + "/" + name;
break;
default:
filePath = Constants.DEFAULT_ROOT + "/" + name;
break;
}
}
return createTestMediaFile(filePath, fileID, context);
}
public static boolean clearProject(String projectname) {
File directory = new File(Constants.DEFAULT_ROOT + "/" + projectname);
if (directory.exists()) {
return UtilFile.deleteDirectory(directory);
}
return false;
}
public static File createTestMediaFile(String filePath, int fileID, Context context) throws IOException {
File testImage = new File(filePath);
if (!testImage.exists()) {
testImage.createNewFile();
}
InputStream in = context.getResources().openRawResource(fileID);
OutputStream out = new BufferedOutputStream(new FileOutputStream(testImage), Constants.BUFFER_8K);
byte[] buffer = new byte[Constants.BUFFER_8K];
int length = 0;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.flush();
out.close();
return testImage;
}
public static String getProjectfileAsString(String projectName) {
File projectFile = new File(Constants.DEFAULT_ROOT + "/" + projectName + "/" + Constants.PROJECTCODE_NAME);
if (!projectFile.exists()) {
return null;
}
StringBuilder contents = new StringBuilder();
try {
BufferedReader input = new BufferedReader(new FileReader(projectFile), Constants.BUFFER_8K);
try {
String line = null;
while ((line = input.readLine()) != null) {
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
} finally {
input.close();
}
} catch (IOException ioException) {
Log.e(TAG, Log.getStackTraceString(ioException));
}
return contents.toString();
}
// private static class ProjectWithCatrobatLanguageVersion extends Project {
// static final long serialVersionUID = 1L;
// private final float catrobatLanguageVersion;
//
// @SuppressWarnings("unused")
// public ProjectWithCatrobatLanguageVersion() {
// catrobatLanguageVersion = 0.1f;
// }
//
// public ProjectWithCatrobatLanguageVersion(String name, float catrobatLanguageVersion) {
// super(null, name);
// this.catrobatLanguageVersion = catrobatLanguageVersion;
// }
//
// @Override
// public float getCatrobatLanguageVersion() {
// return catrobatLanguageVersion;
// }
// }
public static Project createTestProjectOnLocalStorageWithCatrobatLanguageVersionAndName(
float catrobatLanguageVersion, String name) {
// Project project = new ProjectWithCatrobatLanguageVersion(name, catrobatLanguageVersion);
Project project = new Project(null, name);
project.setCatrobatLanguageVersion(catrobatLanguageVersion);
Sprite firstSprite = new SingleSprite("cat");
Script testScript = new StartScript();
Brick testBrick = new HideBrick();
testScript.addBrick(testBrick);
firstSprite.addScript(testScript);
project.getDefaultScene().addSprite(firstSprite);
StorageHandler.getInstance().saveProject(project);
return project;
}
public static List<Brick> createTestProjectWithWrongIfClauseReferences() {
ProjectManager projectManager = ProjectManager.getInstance();
Project project = new Project(null, CORRUPT_PROJECT_NAME);
Sprite firstSprite = new SingleSprite("corruptReferences");
Script testScript = new StartScript();
ArrayList<Brick> brickList = new ArrayList<Brick>();
IfLogicBeginBrick ifBeginBrick = new IfLogicBeginBrick(0);
IfLogicElseBrick ifElseBrick = new IfLogicElseBrick(ifBeginBrick);
ifElseBrick.setIfBeginBrick(null);
IfLogicBeginBrick ifBeginBrickNested = new IfLogicBeginBrick(0);
//reference shouldn't be null:
IfLogicElseBrick ifElseBrickNested = new IfLogicElseBrick(ifBeginBrickNested);
ifElseBrickNested.setIfBeginBrick(null);
//reference shouldn't be null + wrong ifElseBrickReference:
IfLogicEndBrick ifEndBrickNested = new IfLogicEndBrick(ifElseBrick, ifBeginBrickNested);
ifEndBrickNested.setIfBeginBrick(null);
//reference to wrong ifBegin and ifEnd-Bricks:
IfLogicEndBrick ifEndBrick = new IfLogicEndBrick(ifElseBrickNested, ifBeginBrickNested);
brickList.add(ifBeginBrick);
brickList.add(new ShowBrick());
brickList.add(ifElseBrick);
brickList.add(new ComeToFrontBrick());
brickList.add(ifBeginBrickNested);
brickList.add(new ComeToFrontBrick());
brickList.add(ifElseBrickNested);
brickList.add(new ShowBrick());
brickList.add(ifEndBrickNested);
brickList.add(ifEndBrick);
for (Brick brick : brickList) {
testScript.addBrick(brick);
}
firstSprite.addScript(testScript);
project.getDefaultScene().addSprite(firstSprite);
projectManager.setFileChecksumContainer(new FileChecksumContainer());
projectManager.setProject(project);
projectManager.setCurrentSprite(firstSprite);
projectManager.setCurrentScript(testScript);
return brickList;
}
public static Project createTestProjectOnLocalStorageWithCatrobatLanguageVersion(float catrobatLanguageVersion) {
return createTestProjectOnLocalStorageWithCatrobatLanguageVersionAndName(catrobatLanguageVersion,
DEFAULT_TEST_PROJECT_NAME);
}
public static Project createEmptyProject() {
Project project = new Project(null, EMPTY_PROJECT);
StorageHandler.getInstance().saveProject(project);
return project;
}
public static void deleteTestProjects(String... additionalProjectNames) {
Log.d(TAG, "deleteTestProjects");
ProjectManager.getInstance().setFileChecksumContainer(new FileChecksumContainer());
File directory = new File(Constants.DEFAULT_ROOT + "/" + DEFAULT_TEST_PROJECT_NAME);
if (directory.exists()) {
UtilFile.deleteDirectory(directory);
}
for (String name : additionalProjectNames) {
directory = new File(Constants.DEFAULT_ROOT + "/" + name);
if (directory.exists()) {
UtilFile.deleteDirectory(directory);
}
}
}
public static boolean isUrlValidAndReachable(String urlString) {
try {
URL url = new URL(urlString);
InputStream i = null;
try {
i = url.openStream();
} catch (UnknownHostException ex) {
return false;
} catch (IOException ex) {
return false;
}
if (i == null) {
return false;
}
return true;
} catch (MalformedURLException e) {
return false;
}
}
public static void cancelAllNotifications(Context context) {
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
@SuppressWarnings("unchecked")
SparseArray<NotificationData> notificationMap = (SparseArray<NotificationData>) Reflection.getPrivateField(
StatusBarNotificationManager.class, StatusBarNotificationManager.getInstance(), "notificationDataMap");
if (notificationMap == null) {
return;
}
for (int i = 0; i < notificationMap.size(); i++) {
notificationManager.cancel(notificationMap.keyAt(i));
}
notificationMap.clear();
}
public static Script addUserBrickToSpriteAndGetUserScript(UserBrick userBrick, Sprite sprite) {
UserScriptDefinitionBrick definitionBrick = (UserScriptDefinitionBrick) Reflection.getPrivateField(userBrick,
"definitionBrick");
sprite.addUserBrick(userBrick);
return definitionBrick.getScriptSafe();
}
public static void removeFromPreferences(Context context, String key) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor edit = preferences.edit();
edit.remove(key);
edit.commit();
}
public static void loadExistingOrCreateDefaultDroneProject(Context context) {
String droneDefaultProjectName = context.getString(R.string.default_drone_project_name);
try {
ProjectManager.getInstance().loadProject(droneDefaultProjectName, context);
} catch (ProjectException cannotLoadDroneProjectException) {
Log.e(TAG, "Cannot load default drone project", cannotLoadDroneProjectException);
}
String currentName = ProjectManager.getInstance().getCurrentProject().getName();
if (!currentName.equals(droneDefaultProjectName)) {
try {
ProjectManager.getInstance().setProject(createAndSaveDefaultDroneProject(
context));
return;
} catch (IOException ioException) {
Log.e(TAG, "Cannot initialize default drone project.", ioException);
Assert.fail("Cannot initialize default drone project.");
}
}
Assert.fail("Cannot initialize default default drone project.");
}
public static Project createAndSaveDefaultDroneProject(Context context) throws IOException {
Log.d(TAG, "createAndSaveDefaultDroneProject");
String projectName = context.getString(R.string.default_drone_project_name);
return createAndSaveDefaultDroneProject(projectName, context);
}
public static Project createAndSaveDefaultDroneProject(String projectName, Context context) throws IOException,
IllegalArgumentException {
DefaultProjectCreatorDrone defaultProjectCreatorDrone = new DefaultProjectCreatorDrone();
return defaultProjectCreatorDrone.createDefaultProject(projectName, context);
}
public static Project createProjectWithGlobalValues(String name, String spriteName, String valueName, Context context) {
Project project = new Project(context, name);
project.getDefaultScene().getDataContainer().addProjectUserList(valueName);
project.getDefaultScene().getDataContainer().addProjectUserVariable(valueName);
Sprite sprite = new SingleSprite(spriteName);
Script script = new StartScript();
SetVariableBrick variableBrick = new SetVariableBrick(new Formula(1), project.getProjectVariableWithName(valueName));
AddItemToUserListBrick listBrick = new AddItemToUserListBrick(new Formula(1), project.getProjectListWithName(valueName));
script.addBrick(variableBrick);
script.addBrick(listBrick);
sprite.addScript(script);
project.getDefaultScene().getSpriteList().get(0).addScript(script);
project.getDefaultScene().addSprite(sprite);
return project;
}
public static Project createProjectWithSpriteValues(String name, String spriteName, String valueName, Context context) {
Project project = new Project(context, name);
Sprite sprite = new SingleSprite(spriteName);
UserList firstList = project.getDefaultScene().getDataContainer().addSpriteUserListToSprite(project.getDefaultScene().getSpriteList().get(0), valueName);
UserList secondList = project.getDefaultScene().getDataContainer().addSpriteUserListToSprite(sprite, valueName);
UserVariable firstVariable = project.getDefaultScene().getDataContainer().addSpriteUserVariableToSprite(project.getDefaultScene().getSpriteList().get(0), valueName);
UserVariable secondVariable = project.getDefaultScene().getDataContainer().addSpriteUserVariableToSprite(sprite, valueName);
Script firstScript = new StartScript();
Script secondScript = new StartScript();
SetVariableBrick firstVariableBrick = new SetVariableBrick(new Formula(1), firstVariable);
SetVariableBrick secondVariableBrick = new SetVariableBrick(new Formula(1), secondVariable);
AddItemToUserListBrick firstListBrick = new AddItemToUserListBrick(new Formula(1), firstList);
AddItemToUserListBrick secondListBrick = new AddItemToUserListBrick(new Formula(1), secondList);
firstScript.addBrick(firstVariableBrick);
firstScript.addBrick(firstListBrick);
secondScript.addBrick(secondVariableBrick);
secondScript.addBrick(secondListBrick);
sprite.addScript(secondScript);
project.getDefaultScene().getSpriteList().get(0).addScript(firstScript);
project.getDefaultScene().addSprite(sprite);
return project;
}
public static Project createProjectWithOldCollisionFormulas(String name, Context context, String firstSprite,
String secondSprite, String thirdSprite, String collisionTag) {
Project project = new Project(context, name);
project.setCatrobatLanguageVersion(0.992f);
Sprite sprite1 = new Sprite(firstSprite);
Sprite sprite2 = new Sprite(secondSprite);
Sprite sprite3 = new Sprite(thirdSprite);
Script firstScript = new StartScript();
FormulaElement element1 = new FormulaElement(FormulaElement.ElementType.COLLISION_FORMULA, firstSprite + " "
+ collisionTag + " " + thirdSprite, null);
Formula formula1 = new Formula(element1);
IfLogicBeginBrick ifBrick = new IfLogicBeginBrick(formula1);
firstScript.addBrick(ifBrick);
sprite1.addScript(firstScript);
project.getDefaultScene().addSprite(sprite1);
project.getDefaultScene().addSprite(sprite2);
project.getDefaultScene().addSprite(sprite3);
ProjectManager projectManager = ProjectManager.getInstance();
projectManager.setCurrentProject(project);
return project;
}
public static void sleep(int time) {
try {
Thread.sleep((long) time);
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage());
}
}
public static Pixmap createRectanglePixmap(int width, int height, Color color) {
Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
pixmap.setColor(color);
pixmap.fillRectangle(0, 0, width, height);
return pixmap;
}
public static void copyAssetProjectZipFile(Context context, String fileName, String destinationFolder) {
File dstFolder = new File(destinationFolder);
dstFolder.mkdirs();
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
inputStream = context.getResources().getAssets().open(fileName);
outputStream = new FileOutputStream(destinationFolder + "/" + fileName);
byte[] buffer = new byte[1024];
int read;
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
outputStream.flush();
} catch (IOException exception) {
Log.e(TAG, "cannot copy asset project", exception);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException exception) {
Log.e(TAG, "Error closing streams", exception);
}
}
}
}