diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index c956b5436ca..741cd530d67 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -61,6 +61,14 @@
+
+
+
+
+
+
@@ -273,5 +281,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
index 94ef9d401ea..1e2ac1dfa8b 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -98,20 +98,23 @@ pipeline {
// Build the flavors so that they can be installed next independently of older versions.
sh "./gradlew ${useWebTestParameter()} -Pindependent='#$env.BUILD_NUMBER $env.BRANCH_NAME' assembleCatroidDebug ${allFlavoursParameters()}"
+ renameApks("${env.BRANCH_NAME}-${env.BUILD_NUMBER}")
archiveArtifacts '**/*.apk'
}
}
stage('Static Analysis') {
steps {
- sh './gradlew pmd checkstyle lint'
+ sh './gradlew pmd checkstyle lint detekt'
}
post {
always {
- pmd canComputeNew: false, canRunOnFailed: true, defaultEncoding: '', healthy: '', pattern: "catroid/build/reports/pmd.xml", unHealthy: '', unstableTotalAll: '0'
- checkstyle canComputeNew: false, canRunOnFailed: true, defaultEncoding: '', healthy: '', pattern: "catroid/build/reports/checkstyle.xml", unHealthy: '', unstableTotalAll: '0'
- androidLint canComputeNew: false, canRunOnFailed: true, defaultEncoding: '', healthy: '', pattern: "catroid/build/reports/lint*.xml", unHealthy: '', unstableTotalAll: '0'
+ recordIssues aggregatingResults: true, enabledForFailure: true, qualityGates: [[threshold: 1, type: 'TOTAL', unstable: true]],
+ tools: [androidLintParser(pattern: 'catroid/build/reports/lint*.xml'),
+ checkStyle(pattern: 'catroid/build/reports/checkstyle.xml'),
+ pmdParser(pattern: 'catroid/build/reports/pmd.xml'),
+ detekt(pattern: 'catroid/build/reports/detekt/detekt.xml')]
}
}
}
@@ -142,6 +145,36 @@ pipeline {
}
}
+ stage('Legacy Tests') {
+ steps {
+ sh '''./gradlew -PenableCoverage -PlogcatFile=legacy_logcat.txt -Pemulator=android19 \
+ startEmulator createCatroidDebugAndroidTestCoverageReport \
+ -Pandroid.testInstrumentationRunnerArguments.class=org.catrobat.catroid.uiespresso.testsuites.ApiLevel19RegressionTestsSuite'''
+ }
+
+ post {
+ always {
+ postEmulator 'legacy'
+ }
+ }
+ }
+
+ stage('Testrunner Tests') {
+ steps {
+ sh '''./gradlew -PenableCoverage -PlogcatFile=testrunner_logcat.txt -Pemulator=android24 \
+ startEmulator createCatroidDebugAndroidTestCoverageReport \
+ -Pandroid.testInstrumentationRunnerArguments.package=org.catrobat.catroid.catrobattestrunner'''
+
+
+ }
+
+ post {
+ always {
+ postEmulator 'testrunner'
+ }
+ }
+ }
+
stage('Quarantined Tests') {
when {
expression { isJobStartedByTimer() }
diff --git a/Jenkinsfile.buildMetadata b/Jenkinsfile.buildMetadata
index 47d073e64b9..6a102f8b6c4 100644
--- a/Jenkinsfile.buildMetadata
+++ b/Jenkinsfile.buildMetadata
@@ -27,17 +27,26 @@ pipeline {
stage('Prepare build') {
steps {
script {
- currentBuild.displayName = "#${env.BUILD_NUMBER}"
+ currentBuild.displayName = "#${env.BUILD_NUMBER} | ${env.flavor} | ${env.gitBranch}"
}
}
}
stage('Setup Translations') {
steps {
- sh '''
- set +x
- ./gradlew generateCrowdinMetadataCatroid -PcrowdinKey=$crowdinKey
- '''
+ script {
+ if (env.flavor == 'Playground') {
+ sh '''
+ set +x
+ ./gradlew generateCrowdinMetadataCatroid -PcrowdinKey=$crowdinKey
+ '''
+ } else {
+ sh '''
+ set +x
+ ./gradlew generateCrowdinMetadata${flavor} -PcrowdinKey=$crowdinKey
+ '''
+ }
+ }
}
}
@@ -49,7 +58,15 @@ pipeline {
stage('Create Screenshots') {
steps {
- sh "./gradlew generateScreenshotsCatroid"
+ script {
+ if (env.flavor == 'Playground') {
+ sh './gradlew generateScreenshotsCatroid'
+ } else {
+ sh './gradlew generateScreenshots${flavor}'
+ }
+ }
+ zip zipFile: 'metadata.zip', archive: false, dir: 'fastlane/metadata'
+ archiveArtifacts artifacts: 'metadata.zip', fingerprint: true
}
post {
always {
@@ -88,7 +105,7 @@ pipeline {
environment name: 'APPROVE_DEPLOY', value: 'yes'
}
steps {
- sh "fastlane android upload_Metadata_Catroid"
+ sh 'fastlane android upload_Metadata_${flavor}'
}
}
@@ -97,12 +114,24 @@ pipeline {
environment name: 'APPROVE_DEPLOY', value: 'yes'
}
steps {
- sh "fastlane android promote_Catroid"
+ script {
+ if (env.flavor == 'Playground') {
+ echo 'Playground cannot be promoted to production!'
+ } else {
+ // deactivated for testing to not publish by accident
+ //sh 'fastlane android promote_${flavor}'
+ echo 'The promotion of the APK is currently deactivated!'
+ }
+ }
}
}
}
post {
+ always {
+ // clean workspace
+ deleteDir()
+ }
changed {
notifyChat()
}
diff --git a/Jenkinsfile.releaseAPK b/Jenkinsfile.releaseAPK
index ba4eba06d33..8393600d172 100644
--- a/Jenkinsfile.releaseAPK
+++ b/Jenkinsfile.releaseAPK
@@ -27,7 +27,7 @@ pipeline {
stage('Prepare build') {
steps {
script {
- currentBuild.displayName = "#${env.BUILD_NUMBER}"
+ currentBuild.displayName = "#${env.BUILD_NUMBER} | ${env.flavor} | ${env.gitBranch}"
}
}
}
@@ -36,17 +36,46 @@ pipeline {
steps {
// Build, zipalign and sign releasable APK
withCredentials([file(credentialsId: 'a925b6e8-b3c6-407e-8cad-65886e330037', variable: 'SIGNING_KEYSTORE')]) {
- sh '''
- set +x
- ./gradlew assembleCatroidSignedRelease \
- -PsigningKeystore=${SIGNING_KEYSTORE} \
- -PsigningKeystorePassword=$signingKeystorePassword \
- -PsigningKeyAlias=$signingKeyAlias \
- -PsigningKeyPassword=$signingKeyPassword \
- -PfirebaseApiKey=$firebaseApiKey \
- -PfabricApiKey=$fabricApiKey \
- -PfabricApiSecret=$fabricApiSecret
- '''
+ script {
+ if (env.flavor == 'All') {
+ sh '''
+ set +x
+ ./gradlew assembleSignedRelease \
+ -PsigningKeystore=${SIGNING_KEYSTORE} \
+ -PsigningKeystorePassword=$signingKeystorePassword \
+ -PsigningKeyAlias=$signingKeyAlias \
+ -PsigningKeyPassword=$signingKeyPassword \
+ -PfirebaseApiKey=$firebaseApiKey \
+ -PfabricApiKey=$fabricApiKey \
+ -PfabricApiSecret=$fabricApiSecret
+ '''
+ } else if (env.flavor == 'Playground') {
+ sh '''
+ set +x
+ ./gradlew assembleCatroidSignedRelease \
+ -PsigningKeystore=${SIGNING_KEYSTORE} \
+ -PsigningKeystorePassword=$signingKeystorePassword \
+ -PsigningKeyAlias=$signingKeyAlias \
+ -PsigningKeyPassword=$signingKeyPassword \
+ -PfirebaseApiKey=$firebaseApiKey \
+ -PfabricApiKey=$fabricApiKey \
+ -PfabricApiSecret=$fabricApiSecret \
+ -Pplayground=true
+ '''
+ } else {
+ sh '''
+ set +x
+ ./gradlew assemble${flavor}SignedRelease \
+ -PsigningKeystore=${SIGNING_KEYSTORE} \
+ -PsigningKeystorePassword=$signingKeystorePassword \
+ -PsigningKeyAlias=$signingKeyAlias \
+ -PsigningKeyPassword=$signingKeyPassword \
+ -PfirebaseApiKey=$firebaseApiKey \
+ -PfabricApiKey=$fabricApiKey \
+ -PfabricApiSecret=$fabricApiSecret
+ '''
+ }
+ }
}
archiveArtifacts artifacts: 'catroid/build/outputs/apk/**/*signedRelease.apk', fingerprint: true
}
@@ -70,7 +99,18 @@ pipeline {
environment name: 'APPROVE_UPLOAD_APK', value: 'yes'
}
steps {
- sh "fastlane android upload_APK_Catroid"
+ script {
+ if (env.flavor == 'All') {
+ sh '''
+ fastlane android upload_APK_Catroid \
+ fastlane android upload_APK_CreateAtSchool
+ fastlane android upload_APK_LunaAndCat \
+ fastlane android upload_APK_Phiro \
+ '''
+ } else {
+ sh 'fastlane android upload_APK_${flavor}'
+ }
+ }
}
}
}
diff --git a/catroid/build.gradle b/catroid/build.gradle
index d1c3b76adc1..7c16559296b 100644
--- a/catroid/build.gradle
+++ b/catroid/build.gradle
@@ -24,14 +24,19 @@
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
+ google()
jcenter()
}
dependencies {
classpath 'io.fabric.tools:gradle:1.21.5'
- classpath 'com.google.gms:google-services:3.0.0'
+ classpath 'com.google.gms:google-services:4.2.0'
}
}
+plugins {
+ id "io.gitlab.arturbosch.detekt" version "1.0.0-RC14"
+}
+
repositories {
maven { url "https://jitpack.io" }
maven { url 'https://maven.fabric.io/public' }
@@ -92,6 +97,13 @@ apply plugin: 'checkstyle'
apply plugin: 'jacoco-android'
apply plugin: 'pmd'
+detekt {
+ toolVersion = "1.0.0-RC14"
+ config = files("config/detekt.yml")
+ input = files("src")
+ filters = ".*/resources/.*,.*/build/.*"
+}
+
apply from: 'gradle/code_quality_tasks.gradle'
apply from: 'gradle/intellij_config_tasks.gradle'
apply from: 'gradle/standalone_apk_tasks.gradle'
@@ -100,6 +112,7 @@ apply from: 'gradle/release_fastlane_tasks.gradle'
check.dependsOn 'checkstyle'
check.dependsOn 'pmd'
+check.dependsOn 'detekt'
// When -Pindependent was provided on the gradle command the APP name is changed.
// This allows to have multiple Catroid versions installed in parallel for testing purposes.
@@ -111,6 +124,13 @@ if (project.hasProperty('independent')) {
manifestAppName = appName
}
+if (project.hasProperty('playground') && project.getProperties().get('playground') == 'true') {
+ logger.lifecycle('playground true: ' + project.getProperties().get('playground'))
+ appId = 'org.catrobat.catroid.test'
+ appName = 'Catrobat Playground'
+ manifestAppName = appName
+}
+
if (!project.hasProperty("signingKeystore")) {
ext.signingKeystore = "dummyKeystore"
}
@@ -166,9 +186,9 @@ android {
targetSdkVersion 26
applicationId appId
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
- versionCode 59
+ versionCode 60
println "VersionCode is $versionCode"
- versionName "0.9.56"
+ versionName "0.9.58"
println "VersionName is $versionName"
buildConfigField "String", "GIT_COMMIT_INFO", "\"${getGitCommitInfo()}\""
buildConfigField "String", "MAIN_URL_HTTPS", (project.hasProperty('useWebTest') ? '"https://web-test.catrob.at"' : '"https://share.catrob.at"')
@@ -199,6 +219,11 @@ android {
htmlOutput file("build/reports/lint-report.html")
}
+ testOptions {
+ unitTests.returnDefaultValues = true
+ unitTests.includeAndroidResources = true
+ }
+
dexOptions.javaMaxHeapSize "4g"
packagingOptions {
@@ -247,6 +272,7 @@ android {
buildConfigField "boolean", "FEATURE_CLOUD_MESSAGING_ENABLED", "true"
buildConfigField "boolean", "CRASHLYTICS_CRASH_REPORT_ENABLED", "true"
buildConfigField "boolean", "USE_ANDROID_LOCALES_FOR_SCREENSHOTS", useAndroidLocales()
+ buildConfigField "boolean", "FEATURE_MERGE_ENABLED", "true"
resValue "string", "SNACKBAR_HINTS_ENABLED", "false"
ext.enableCrashlytics = false
testCoverageEnabled = project.hasProperty('enableCoverage')
@@ -269,6 +295,7 @@ android {
buildConfigField "boolean", "FEATURE_CLOUD_MESSAGING_ENABLED", "false"
buildConfigField "boolean", "CRASHLYTICS_CRASH_REPORT_ENABLED", "true"
buildConfigField "boolean", "USE_ANDROID_LOCALES_FOR_SCREENSHOTS", "false"
+ buildConfigField "boolean", "FEATURE_MERGE_ENABLED", "false"
resValue "string", "SNACKBAR_HINTS_ENABLED", "true"
}
@@ -279,6 +306,10 @@ android {
}
flavorDimensions "default"
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
productFlavors {
catroid {
@@ -347,7 +378,7 @@ ext {
mockitoVersion = "2.8.47"
espressoVersion = "3.0.1"
supportLibraryVersion = "27.1.0"
- paintroidVersion = "2.3.1"
+ paintroidVersion = "2.3.2"
}
configurations {
@@ -431,6 +462,14 @@ dependencies {
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-core:$mockitoVersion"
+ testImplementation 'org.hamcrest:hamcrest-library:1.3'
+
+ testImplementation 'org.powermock:powermock:1.6.6'
+ testImplementation 'org.powermock:powermock-module-junit4:2.0.0'
+ testImplementation 'org.powermock:powermock-api-mockito2:2.0.0'
+
+ testImplementation 'org.robolectric:robolectric:4.2.1'
+ testImplementation "org.robolectric:shadows-multidex:4.2.1"
androidTestImplementation fileTree(include: '*.jar', dir: 'src/androidTest/libs')
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0'
@@ -447,6 +486,8 @@ dependencies {
pmd 'net.sourceforge.pmd:pmd-java:5.8.1'
checkstyle 'com.puppycrawl.tools:checkstyle:7.6'
+
+ detektPlugins "io.gitlab.arturbosch.detekt:detekt-formatting:1.0.0-RC14"
}
static def getGitCommitInfo() {
diff --git a/catroid/config/detekt.yml b/catroid/config/detekt.yml
new file mode 100644
index 00000000000..82c31b657c2
--- /dev/null
+++ b/catroid/config/detekt.yml
@@ -0,0 +1,504 @@
+autoCorrect: true
+
+test-pattern: # Configure exclusions for test sources
+ active: true
+ patterns: # Test file regexes
+ - '.*/test/.*'
+ - '.*/androidTest/.*'
+ - '.*Test.kt'
+ - '.*Spec.kt'
+ - '.*Spek.kt'
+ exclude-rule-sets:
+ - 'comments'
+ exclude-rules:
+ - 'NamingRules'
+ - 'WildcardImport'
+ - 'MagicNumber'
+ - 'MaxLineLength'
+ - 'LateinitUsage'
+ - 'StringLiteralDuplication'
+ - 'SpreadOperator'
+ - 'TooManyFunctions'
+ - 'ForEachOnRange'
+ - 'FunctionMaxLength'
+ - 'TooGenericExceptionCaught'
+ - 'InstanceOfCheckForException'
+
+build:
+ maxIssues: 0
+ weights:
+ # complexity: 2
+ # LongParameterList: 1
+ # style: 1
+ # comments: 1
+
+processors:
+ active: true
+ exclude:
+ # - 'FunctionCountProcessor'
+ # - 'PropertyCountProcessor'
+ # - 'ClassCountProcessor'
+ # - 'PackageCountProcessor'
+ # - 'KtFileCountProcessor'
+
+console-reports:
+ active: true
+ exclude:
+ # - 'ProjectStatisticsReport'
+ # - 'ComplexityReport'
+ # - 'NotificationReport'
+ # - 'FindingsReport'
+ # - 'BuildFailureReport'
+
+complexity:
+ active: true
+ ComplexCondition:
+ active: true
+ threshold: 4
+ ComplexInterface:
+ active: false
+ threshold: 10
+ includeStaticDeclarations: false
+ ComplexMethod:
+ active: true
+ threshold: 10
+ ignoreSingleWhenExpression: true
+ ignoreSimpleWhenEntries: true
+ LabeledExpression:
+ active: false
+ ignoredLabels: ""
+ LargeClass:
+ active: true
+ threshold: 600
+ LongMethod:
+ active: true
+ threshold: 60
+ LongParameterList:
+ active: true
+ threshold: 6
+ ignoreDefaultParameters: false
+ MethodOverloading:
+ active: true
+ threshold: 2
+ NestedBlockDepth:
+ active: true
+ threshold: 4
+ StringLiteralDuplication:
+ active: true
+ threshold: 3
+ ignoreAnnotation: true
+ excludeStringsWithLessThan5Characters: true
+ ignoreStringsRegex: '$^'
+ TooManyFunctions:
+ active: false
+ thresholdInFiles: 11
+ thresholdInClasses: 11
+ thresholdInInterfaces: 11
+ thresholdInObjects: 11
+ thresholdInEnums: 11
+ ignoreDeprecated: false
+ ignorePrivate: false
+ ignoreOverridden: false
+
+empty-blocks:
+ active: true
+ EmptyCatchBlock:
+ active: true
+ allowedExceptionNameRegex: "^expected.*"
+ EmptyClassBlock:
+ active: true
+ EmptyDefaultConstructor:
+ active: true
+ EmptyDoWhileBlock:
+ active: true
+ EmptyElseBlock:
+ active: true
+ EmptyFinallyBlock:
+ active: true
+ EmptyForBlock:
+ active: true
+ EmptyFunctionBlock:
+ active: true
+ ignoreOverriddenFunctions: false
+ EmptyIfBlock:
+ active: true
+ EmptyInitBlock:
+ active: true
+ EmptyKtFile:
+ active: true
+ EmptySecondaryConstructor:
+ active: true
+ EmptyWhenBlock:
+ active: true
+ EmptyWhileBlock:
+ active: true
+
+exceptions:
+ active: true
+ ExceptionRaisedInUnexpectedLocation:
+ active: true
+ methodNames: 'toString,hashCode,equals,finalize'
+ InstanceOfCheckForException:
+ active: true
+ NotImplementedDeclaration:
+ active: true
+ PrintStackTrace:
+ active: true
+ RethrowCaughtException:
+ active: true
+ ReturnFromFinally:
+ active: true
+ SwallowedException:
+ active: true
+ ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException'
+ ThrowingExceptionFromFinally:
+ active: true
+ ThrowingExceptionInMain:
+ active: true
+ ThrowingExceptionsWithoutMessageOrCause:
+ active: true
+ exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
+ ThrowingNewInstanceOfSameException:
+ active: true
+ TooGenericExceptionCaught:
+ active: true
+ exceptionNames:
+ - ArrayIndexOutOfBoundsException
+ - Error
+ - Exception
+ - IllegalMonitorStateException
+ - NullPointerException
+ - IndexOutOfBoundsException
+ - RuntimeException
+ - Throwable
+ allowedExceptionNameRegex: "^expected.*"
+ TooGenericExceptionThrown:
+ active: true
+ exceptionNames:
+ - Error
+ - Exception
+ - Throwable
+ - RuntimeException
+
+formatting:
+ active: true
+ android: true
+ autoCorrect: true
+ ChainWrapping:
+ active: true
+ autoCorrect: true
+ CommentSpacing:
+ active: true
+ autoCorrect: true
+ Filename:
+ active: true
+ FinalNewline:
+ active: true
+ autoCorrect: true
+ ImportOrdering:
+ active: false
+ Indentation:
+ active: true
+ autoCorrect: true
+ indentSize: 4
+ continuationIndentSize: 4
+ MaximumLineLength:
+ active: false
+ maxLineLength: 120
+ ModifierOrdering:
+ active: true
+ autoCorrect: true
+ NoBlankLineBeforeRbrace:
+ active: true
+ autoCorrect: true
+ NoConsecutiveBlankLines:
+ active: true
+ autoCorrect: true
+ NoEmptyClassBody:
+ active: true
+ autoCorrect: true
+ NoItParamInMultilineLambda:
+ active: false
+ NoLineBreakAfterElse:
+ active: true
+ autoCorrect: true
+ NoLineBreakBeforeAssignment:
+ active: true
+ autoCorrect: true
+ NoMultipleSpaces:
+ active: true
+ autoCorrect: true
+ NoSemicolons:
+ active: true
+ autoCorrect: true
+ NoTrailingSpaces:
+ active: true
+ autoCorrect: true
+ NoUnitReturn:
+ active: true
+ autoCorrect: true
+ NoUnusedImports:
+ active: true
+ autoCorrect: true
+ NoWildcardImports:
+ active: true
+ autoCorrect: true
+ PackageName:
+ active: true
+ autoCorrect: true
+ ParameterListWrapping:
+ active: true
+ autoCorrect: true
+ indentSize: 4
+ SpacingAroundColon:
+ active: true
+ autoCorrect: true
+ SpacingAroundComma:
+ active: true
+ autoCorrect: true
+ SpacingAroundCurly:
+ active: true
+ autoCorrect: true
+ SpacingAroundKeyword:
+ active: true
+ autoCorrect: true
+ SpacingAroundOperators:
+ active: true
+ autoCorrect: true
+ SpacingAroundParens:
+ active: true
+ autoCorrect: true
+ SpacingAroundRangeOperator:
+ active: true
+ autoCorrect: true
+ StringTemplate:
+ active: true
+ autoCorrect: true
+
+naming:
+ active: true
+ ClassNaming:
+ active: true
+ classPattern: '[A-Z$][a-zA-Z0-9$]*'
+ ConstructorParameterNaming:
+ active: true
+ parameterPattern: '[a-z][A-Za-z0-9]*'
+ privateParameterPattern: '[a-z][A-Za-z0-9]*'
+ excludeClassPattern: '$^'
+ EnumNaming:
+ active: true
+ enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
+ ForbiddenClassName:
+ active: false
+ forbiddenName: ''
+ FunctionMaxLength:
+ active: false
+ maximumFunctionNameLength: 30
+ FunctionMinLength:
+ active: false
+ minimumFunctionNameLength: 3
+ FunctionNaming:
+ active: true
+ functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
+ excludeClassPattern: '$^'
+ ignoreOverridden: true
+ FunctionParameterNaming:
+ active: true
+ parameterPattern: '[a-z][A-Za-z0-9]*'
+ excludeClassPattern: '$^'
+ ignoreOverriddenFunctions: true
+ MatchingDeclarationName:
+ active: true
+ MemberNameEqualsClassName:
+ active: false
+ ignoreOverriddenFunction: true
+ ObjectPropertyNaming:
+ active: true
+ constantPattern: '[A-Za-z][_A-Za-z0-9]*'
+ propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
+ privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
+ PackageNaming:
+ active: true
+ packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$'
+ TopLevelPropertyNaming:
+ active: true
+ constantPattern: '[A-Z][_A-Z0-9]*'
+ propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
+ privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
+ VariableMaxLength:
+ active: false
+ maximumVariableNameLength: 64
+ VariableMinLength:
+ active: false
+ minimumVariableNameLength: 1
+ VariableNaming:
+ active: true
+ variablePattern: '[a-z][A-Za-z0-9]*'
+ privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
+ excludeClassPattern: '$^'
+ ignoreOverridden: true
+
+performance:
+ active: true
+ ArrayPrimitive:
+ active: true
+ ForEachOnRange:
+ active: true
+ SpreadOperator:
+ active: true
+ UnnecessaryTemporaryInstantiation:
+ active: true
+
+potential-bugs:
+ active: true
+ DuplicateCaseInWhenExpression:
+ active: true
+ EqualsAlwaysReturnsTrueOrFalse:
+ active: true
+ EqualsWithHashCodeExist:
+ active: true
+ ExplicitGarbageCollectionCall:
+ active: true
+ InvalidRange:
+ active: true
+ IteratorHasNextCallsNextMethod:
+ active: true
+ IteratorNotThrowingNoSuchElementException:
+ active: true
+ LateinitUsage:
+ active: false
+ excludeAnnotatedProperties: ""
+ ignoreOnClassesPattern: ""
+ UnconditionalJumpStatementInLoop:
+ active: true
+ UnreachableCode:
+ active: true
+ UnsafeCallOnNullableType:
+ active: true
+ UnsafeCast:
+ active: true
+ UselessPostfixExpression:
+ active: true
+ WrongEqualsTypeParameter:
+ active: true
+
+style:
+ active: true
+ CollapsibleIfStatements:
+ active: true
+ DataClassContainsFunctions:
+ active: true
+ conversionFunctionPrefix: 'to'
+ EqualsNullCall:
+ active: true
+ EqualsOnSignatureLine:
+ active: true
+ ExplicitItLambdaParameter:
+ active: true
+ ExpressionBodySyntax:
+ active: true
+ includeLineWrapping: false
+ ForbiddenComment:
+ active: true
+ values: 'TODO,FIXME,STOPSHIP'
+ ForbiddenImport:
+ active: false
+ imports: ''
+ ForbiddenVoid:
+ active: true
+ FunctionOnlyReturningConstant:
+ active: true
+ ignoreOverridableFunction: true
+ excludedFunctions: 'describeContents'
+ LoopWithTooManyJumpStatements:
+ active: true
+ maxJumpCount: 1
+ MagicNumber:
+ active: true
+ ignoreNumbers: '-1,0,1,2'
+ ignoreHashCodeFunction: true
+ ignorePropertyDeclaration: false
+ ignoreConstantDeclaration: true
+ ignoreCompanionObjectPropertyDeclaration: true
+ ignoreAnnotation: false
+ ignoreNamedArgument: true
+ ignoreEnums: false
+ MandatoryBracesIfStatements:
+ active: true
+ MaxLineLength:
+ active: false
+ maxLineLength: 120
+ excludePackageStatements: true
+ excludeImportStatements: true
+ excludeCommentStatements: false
+ MayBeConst:
+ active: false
+ ModifierOrder:
+ active: true
+ NestedClassesVisibility:
+ active: true
+ NewLineAtEndOfFile:
+ active: true
+ NoTabs:
+ active: true
+ OptionalAbstractKeyword:
+ active: true
+ OptionalUnit:
+ active: true
+ OptionalWhenBraces:
+ active: true
+ PreferToOverPairSyntax:
+ active: true
+ ProtectedMemberInFinalClass:
+ active: true
+ RedundantVisibilityModifierRule:
+ active: true
+ ReturnCount:
+ active: false
+ max: 2
+ excludedFunctions: "equals"
+ excludeLabeled: false
+ excludeReturnFromLambda: true
+ SafeCast:
+ active: true
+ SerialVersionUIDInSerializableClass:
+ active: true
+ SpacingBetweenPackageAndImports:
+ active: true
+ ThrowsCount:
+ active: true
+ max: 2
+ TrailingWhitespace:
+ active: true
+ UnderscoresInNumericLiterals:
+ active: true
+ acceptableDecimalLength: 5
+ UnnecessaryAbstractClass:
+ active: true
+ excludeAnnotatedClasses: "dagger.Module"
+ UnnecessaryApply:
+ active: true
+ UnnecessaryInheritance:
+ active: true
+ UnnecessaryLet:
+ active: true
+ UnnecessaryParentheses:
+ active: true
+ UntilInsteadOfRangeTo:
+ active: true
+ UnusedImports:
+ active: true
+ UnusedPrivateClass:
+ active: true
+ UnusedPrivateMember:
+ active: true
+ allowedNames: "(_|ignored|expected|serialVersionUID)"
+ UseDataClass:
+ active: true
+ excludeAnnotatedClasses: ""
+ UtilityClassWithPublicConstructor:
+ active: true
+ VarCouldBeVal:
+ active: true
+ WildcardImport:
+ active: true
diff --git a/catroid/gradle/release_fastlane_tasks.gradle b/catroid/gradle/release_fastlane_tasks.gradle
index e80fc889199..c38c9f9ab6e 100644
--- a/catroid/gradle/release_fastlane_tasks.gradle
+++ b/catroid/gradle/release_fastlane_tasks.gradle
@@ -65,7 +65,7 @@ android.productFlavors.all { flavor ->
String fastlaneCommand = "fastlane screengrab" +
" --app_package_name 'org.catrobat.catroid'" +
- " --use_tests_in_packages 'org.catrobat.catroid.screenshots.${flavor.name}'" +
+ " --use_tests_in_packages 'org.catrobat.catroid.screenshots.${flavor.name.toLowerCase()}'" +
" --app_apk_path './catroid/build/outputs/apk/${flavor.name}/debug/catroid-${flavor.name}-debug.apk'" +
" --tests_apk_path './catroid/build/outputs/apk/androidTest/${flavor.name}/debug/catroid-${flavor.name}-debug-androidTest.apk'" +
" --test_instrumentation_runner 'android.support.test.runner.AndroidJUnitRunner'" +
diff --git a/catroid/src/androidTest/assets/TestUserDataConversion0999To09991.catrobat b/catroid/src/androidTest/assets/TestUserDataConversion0999To09991.catrobat
new file mode 100644
index 00000000000..19b6cc7fbe0
Binary files /dev/null and b/catroid/src/androidTest/assets/TestUserDataConversion0999To09991.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailDoubleNotEqual.catrobat b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailDoubleNotEqual.catrobat
new file mode 100644
index 00000000000..ba9d2f2a130
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailDoubleNotEqual.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailMismatchingTypes.catrobat b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailMismatchingTypes.catrobat
new file mode 100644
index 00000000000..0cd56782cc7
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailMismatchingTypes.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailMissingTestVariables.catrobat b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailMissingTestVariables.catrobat
new file mode 100644
index 00000000000..43a9c6022d4
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailMissingTestVariables.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailStringNotEqual.catrobat b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailStringNotEqual.catrobat
new file mode 100644
index 00000000000..30c58f2d0d9
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailStringNotEqual.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailTimeout.catrobat b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailTimeout.catrobat
new file mode 100644
index 00000000000..bf9758376c6
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTestRunnerTests/fail/testFailTimeout.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTestRunnerTests/success/testSuccessDoubleEqual.catrobat b/catroid/src/androidTest/assets/catrobatTestRunnerTests/success/testSuccessDoubleEqual.catrobat
new file mode 100644
index 00000000000..80b0a75d6f3
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTestRunnerTests/success/testSuccessDoubleEqual.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTestRunnerTests/success/testSuccessStringEqual.catrobat b/catroid/src/androidTest/assets/catrobatTestRunnerTests/success/testSuccessStringEqual.catrobat
new file mode 100644
index 00000000000..755ee682cca
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTestRunnerTests/success/testSuccessStringEqual.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/broadcast/testMultipleBroadcastReceivers.catrobat b/catroid/src/androidTest/assets/catrobatTests/broadcast/testMultipleBroadcastReceivers.catrobat
new file mode 100644
index 00000000000..b5291d07ea9
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/broadcast/testMultipleBroadcastReceivers.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testBrickInWhenStartAsCloneCommentedOutRegression.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testBrickInWhenStartAsCloneCommentedOutRegression.catrobat
new file mode 100644
index 00000000000..fd1c428d5ef
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testBrickInWhenStartAsCloneCommentedOutRegression.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testCloneBroadcastListenerOtherSprite.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testCloneBroadcastListenerOtherSprite.catrobat
new file mode 100644
index 00000000000..462907442e0
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testCloneBroadcastListenerOtherSprite.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testCloneBroadcastListenerSameSprite.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testCloneBroadcastListenerSameSprite.catrobat
new file mode 100644
index 00000000000..edb501dbc9b
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testCloneBroadcastListenerSameSprite.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testClonesNotRemovedOnContinueScene.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testClonesNotRemovedOnContinueScene.catrobat
new file mode 100644
index 00000000000..0c962950211
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testClonesNotRemovedOnContinueScene.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testClonesRemovedOnReStartScene.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testClonesRemovedOnReStartScene.catrobat
new file mode 100644
index 00000000000..e152fdd38c6
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testClonesRemovedOnReStartScene.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneBroadcastListenerOtherSpriteRemoved.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneBroadcastListenerOtherSpriteRemoved.catrobat
new file mode 100644
index 00000000000..ecd6267330c
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneBroadcastListenerOtherSpriteRemoved.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneBroadcastListenerRemoved.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneBroadcastListenerRemoved.catrobat
new file mode 100644
index 00000000000..f5791bc723b
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneBroadcastListenerRemoved.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneInParentSpriteDoesNothing.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneInParentSpriteDoesNothing.catrobat
new file mode 100644
index 00000000000..fa535bb6bef
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneInParentSpriteDoesNothing.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneScriptStopped.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneScriptStopped.catrobat
new file mode 100644
index 00000000000..958a578b1d7
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testDeleteCloneScriptStopped.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneMultiple.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneMultiple.catrobat
new file mode 100644
index 00000000000..0fdd3662f09
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneMultiple.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOnlyCalledByClone.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOnlyCalledByClone.catrobat
new file mode 100644
index 00000000000..fd7157dcd0e
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOnlyCalledByClone.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOtherSpriteMultiple.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOtherSpriteMultiple.catrobat
new file mode 100644
index 00000000000..cd5b9860bcc
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOtherSpriteMultiple.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOtherSpriteSingle.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOtherSpriteSingle.catrobat
new file mode 100644
index 00000000000..fd12b8d03af
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneOtherSpriteSingle.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneSingle.catrobat b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneSingle.catrobat
new file mode 100644
index 00000000000..e0641d63b1b
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/clone/testWhenStartAsCloneSingle.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/formula/testSinusFunction.catrobat b/catroid/src/androidTest/assets/catrobatTests/formula/testSinusFunction.catrobat
new file mode 100644
index 00000000000..03253c4b980
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/formula/testSinusFunction.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/sceneTransition/continueSuspendedThreadsOnContinueScene.catrobat b/catroid/src/androidTest/assets/catrobatTests/sceneTransition/continueSuspendedThreadsOnContinueScene.catrobat
new file mode 100644
index 00000000000..9b89c36200f
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/sceneTransition/continueSuspendedThreadsOnContinueScene.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/sceneTransition/discardSuspendedThreadsOnStartScene.catrobat b/catroid/src/androidTest/assets/catrobatTests/sceneTransition/discardSuspendedThreadsOnStartScene.catrobat
new file mode 100644
index 00000000000..f1c8a589a54
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/sceneTransition/discardSuspendedThreadsOnStartScene.catrobat differ
diff --git a/catroid/src/androidTest/assets/catrobatTests/sceneTransition/suspendAllThreadsOnSceneTransition.catrobat b/catroid/src/androidTest/assets/catrobatTests/sceneTransition/suspendAllThreadsOnSceneTransition.catrobat
new file mode 100644
index 00000000000..04bdf6db7cf
Binary files /dev/null and b/catroid/src/androidTest/assets/catrobatTests/sceneTransition/suspendAllThreadsOnSceneTransition.catrobat differ
diff --git a/catroid/src/androidTest/java/org/catrobat/catroid/catrobattestrunner/CatrobatTestRunner.java b/catroid/src/androidTest/java/org/catrobat/catroid/catrobattestrunner/CatrobatTestRunner.java
new file mode 100644
index 00000000000..6b747080913
--- /dev/null
+++ b/catroid/src/androidTest/java/org/catrobat/catroid/catrobattestrunner/CatrobatTestRunner.java
@@ -0,0 +1,210 @@
+/*
+ * Catroid: An on-device visual programming system for Android devices
+ * Copyright (C) 2010-2018 The Catrobat Team
+ * ()
+ *
+ * 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 .
+ */
+package org.catrobat.catroid.catrobattestrunner;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.google.common.math.DoubleMath;
+
+import org.catrobat.catroid.ProjectManager;
+import org.catrobat.catroid.common.Constants;
+import org.catrobat.catroid.content.Project;
+import org.catrobat.catroid.content.bricks.AssertEqualsBrick;
+import org.catrobat.catroid.formulaeditor.UserVariable;
+import org.catrobat.catroid.io.StorageOperations;
+import org.catrobat.catroid.io.asynctask.ProjectLoadTask;
+import org.catrobat.catroid.io.asynctask.ProjectUnzipAndImportTask;
+import org.catrobat.catroid.stage.StageActivity;
+import org.catrobat.catroid.test.utils.TestUtils;
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.fail;
+import static junit.framework.TestCase.assertTrue;
+
+import static org.catrobat.catroid.common.Constants.CACHE_DIR;
+import static org.catrobat.catroid.common.FlavoredConstants.DEFAULT_ROOT_DIRECTORY;
+
+@RunWith(Parameterized.class)
+public class CatrobatTestRunner {
+
+ @Rule
+ public ActivityTestRule baseActivityTestRule = new
+ ActivityTestRule<>(StageActivity.class, true, false);
+
+ private static final String TEST_ASSETS_ROOT = "catrobatTests";
+
+ private static final int TIMEOUT = 10000;
+
+ private static final double EPSILON = 0.000000000001;
+
+ private UserVariable actualVariable;
+ private UserVariable expectedVariable;
+ private UserVariable readyVariable;
+
+ @Parameterized.Parameters(name = "{0} - {1}")
+ public static Iterable