Merge pull request #2163 from MilosKozak/adrian/semantic-versioning

Adrian/semantic versioning
This commit is contained in:
AdrianLxM 2019-10-31 08:38:44 +01:00 committed by GitHub
commit cdecf790e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 296 additions and 17 deletions

View file

@ -15,21 +15,14 @@ import java.io.IOException
import java.net.URL
import java.util.concurrent.TimeUnit
// check network connection
fun isConnected(): Boolean {
val connMgr = MainApp.instance().applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return connMgr.activeNetworkInfo?.isConnected ?: false
}
fun findVersion(file :String?): String? {
val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex()
return file?.lines()?.filter { regex.matches(it) }?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull()
}
private val log = LoggerFactory.getLogger(L.CORE)
fun triggerCheckVersion() {
if (!SP.contains(R.string.key_last_time_this_version_detected)) {
@ -56,13 +49,34 @@ private fun checkVersion() = if (isConnected()) {
log.debug("Github master version no checked. No connectivity")
fun compareWithCurrentVersion(newVersion: String?, currentVersion: String) {
val comparison: Int? = newVersion?.versionStrip()?.compareTo(currentVersion.versionStrip())
when {
comparison == null -> onVersionNotDetectable()
comparison == 0 -> onSameVersionDetected()
comparison > 0 -> onNewVersionDetected(currentVersion = currentVersion, newVersion = newVersion)
else -> onOlderVersionDetected()
val newVersionElements = newVersion.toNumberList()
val currentVersionElements = currentVersion.toNumberList()
if (newVersionElements == null || newVersionElements.isEmpty()) {
onVersionNotDetectable()
return
}
if (currentVersionElements == null || currentVersionElements.isEmpty()) {
// current version scrambled?!
onNewVersionDetected(currentVersion, newVersion)
return
}
newVersionElements.take(3).forEachIndexed { i, newElem ->
val currElem: Int = currentVersionElements.getOrNull(i)
?: return onNewVersionDetected(currentVersion, newVersion)
(newElem - currElem).let {
when {
it > 0 -> return onNewVersionDetected(currentVersion, newVersion)
it < 0 -> return onOlderVersionDetected()
it == 0 -> Unit
}
}
}
onSameVersionDetected()
}
private fun onOlderVersionDetected() {
@ -75,7 +89,7 @@ fun onSameVersionDetected() {
}
fun onVersionNotDetectable() {
log.debug("fetch failed, ignore and smartcast to non-null")
log.debug("fetch failed")
}
fun onNewVersionDetected(currentVersion: String, newVersion: String?) {
@ -88,14 +102,25 @@ fun onNewVersionDetected(currentVersion: String, newVersion: String?) {
}
}
@Deprecated(replaceWith = ReplaceWith("numericVersionPart()"), message = "Will not work if RCs have another index number in it.")
fun String.versionStrip() = this.mapNotNull {
when (it) {
in '0'..'9' -> it
'.' -> it
else -> null
'.' -> it
else -> null
}
}.joinToString(separator = "")
fun String.numericVersionPart(): String =
"(((\\d+)\\.)+(\\d+))(\\D(.*))?".toRegex().matchEntire(this)?.groupValues?.getOrNull(1) ?: ""
fun String?.toNumberList() =
this?.numericVersionPart().takeIf { !it.isNullOrBlank() }?.split(".")?.map { it.toInt() }
fun findVersion(file: String?): String? {
val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex()
return file?.lines()?.filter { regex.matches(it) }?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull()
}
val CHECK_EVERY = TimeUnit.DAYS.toMillis(1)
val WARN_EVERY = TimeUnit.DAYS.toMillis(1)

View file

@ -16,6 +16,70 @@ import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
class VersionCheckerUtilsKtTest {
@Test
fun `should keep 2 digit version`() {
assertEquals("1.2", "1.2".numericVersionPart())
}
@Test
fun `should keep 3 digit version`() {
assertEquals("1.2.3", "1.2.3".numericVersionPart())
}
@Test
fun `should keep 4 digit version`() {
assertEquals("1.2.3.4", "1.2.3.4".numericVersionPart())
}
@Test
fun `should strip 2 digit version RC`() {
assertEquals("1.2", "1.2-RC1".numericVersionPart())
}
@Test
fun `should strip 2 digit version RC old format`() {
assertEquals("1.2", "1.2RC1".numericVersionPart())
}
@Test
fun `should strip 2 digit version RC without digit`() {
assertEquals("1.2", "1.2-RC".numericVersionPart())
}
@Test
fun `should strip 2 digit version dev`() {
assertEquals("1.2", "1.2-dev".numericVersionPart())
}
@Test
fun `should strip 2 digit version dev old format 1`() {
assertEquals("1.2", "1.2dev".numericVersionPart())
}
@Test
fun `should strip 2 digit version dev old format 2`() {
assertEquals("1.2", "1.2dev-a3".numericVersionPart())
}
@Test
fun `should strip 3 digit version RC`() {
assertEquals("1.2.3", "1.2.3-RC1".numericVersionPart())
}
@Test
fun `should strip 4 digit version RC`() {
assertEquals("1.2.3.4", "1.2.3.4-RC5".numericVersionPart())
}
@Test
fun `should strip even with dot`() {
assertEquals("1.2", "1.2.RC5".numericVersionPart())
}
@Test
fun findVersionMatchesRegularVersion() {
val buildGradle = """blabla
@ -154,6 +218,33 @@ class VersionCheckerUtilsKtTest {
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should not find update on fourth version digit`() {
prepareMainApp()
compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0.1")
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `should not find update on personal version with same number` (){
prepareMainApp()
compareWithCurrentVersion(newVersion = "2.5.0", currentVersion = "2.5.0-myversion")
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find same version`() {
@ -177,6 +268,27 @@ class VersionCheckerUtilsKtTest {
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "3.0.0"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "2.2.2")
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version with longer number`() {
val buildGradle = """blabla
| android {
| aosenuthoae
@ -194,6 +306,148 @@ class VersionCheckerUtilsKtTest {
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "3.0.0"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "3.0-RC04")
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC 2 - typo`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "3.0.0"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "3.0RC04")
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC 3 - typo`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "3.0.0"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "3.RC04")
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version after RC 4 - typo`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "3.0.0"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "3.0.RC04")
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `find higher version on multi digit numbers`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "3.7.12"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "3.7.9")
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.getLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_versionchecker_warning), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `don't find higher version on higher but shorter version`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "2.2.2"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "2.3")
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(MainApp::class, L::class, SP::class)
fun `don't find higher version if on next RC`() {
val buildGradle = """blabla
| android {
| aosenuthoae
| }
| version = "2.2.2"
| appName = "Aaoeu"
""".trimMargin()
prepareMainApp()
compareWithCurrentVersion(findVersion(buildGradle), currentVersion = "2.3-RC")
//verify(bus, times(0)).post(any())
PowerMockito.verifyStatic(SP::class.java, times(1))
SP.putLong(eq(R.string.key_last_time_this_version_detected), ArgumentMatchers.anyLong())
PowerMockito.verifyNoMoreInteractions(SP::class.java)
}
@Test
@PrepareForTest(System::class)
@ -221,4 +475,4 @@ class VersionCheckerUtilsKtTest {
`when`(L.isEnabled(any())).thenReturn(true)
}
}
}