From 5b7fdcd6a97219ac6e1449aa203769b6c229fb2a Mon Sep 17 00:00:00 2001 From: bvn13 Date: Thu, 29 Sep 2022 15:32:40 +0300 Subject: [PATCH 1/3] Update for next development version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 90bae53..da4945b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ GpxAndroidSdk me.bvn13.sdk.android.gpx - 1.1 + 1.2-SNAPSHOT jar From 6589c3321befa769d4bfb63baf58f1df92617541 Mon Sep 17 00:00:00 2001 From: bvn13 Date: Thu, 29 Sep 2022 19:34:37 +0300 Subject: [PATCH 2/3] fixed line formatting --- pom.xml | 12 +- .../me/bvn13/sdk/android/gpx/GpxWriter.kt | 186 +++-- .../me/bvn13/sdk/android/gpx/GpxWriterTest.kt | 689 ++++++++++-------- 3 files changed, 466 insertions(+), 421 deletions(-) diff --git a/pom.xml b/pom.xml index da4945b..94c474c 100644 --- a/pom.xml +++ b/pom.xml @@ -82,15 +82,9 @@ ${kotlin-junit.version} - io.kotest - kotest-runner-junit5-jvm - ${kotest.version} - test - - - io.kotest - kotest-assertions-core-jvm - ${kotest.version} + org.junit.jupiter + junit-jupiter-api + ${jupiter.version} test diff --git a/src/main/kotlin/me/bvn13/sdk/android/gpx/GpxWriter.kt b/src/main/kotlin/me/bvn13/sdk/android/gpx/GpxWriter.kt index 6a651ed..67cc664 100644 --- a/src/main/kotlin/me/bvn13/sdk/android/gpx/GpxWriter.kt +++ b/src/main/kotlin/me/bvn13/sdk/android/gpx/GpxWriter.kt @@ -99,11 +99,11 @@ fun GpxType.toXmlString(clock: Clock?): String = """ xsi:schemaLocation="$SCHEMA_LOCATION"> ${this.metadata.toXmlString()} - ${this.wpt?.toXmlString()} - ${this.rte?.toXmlString()} - ${this.trk?.toXmlString()} + ${this.wpt?.toXmlString() ?: ""} + ${this.rte?.toXmlString() ?: ""} + ${this.trk?.toXmlString() ?: ""} -""".trim() +""".trim().removeEmptyStrings() fun MetadataType.toXmlString(): String = """ @@ -113,16 +113,13 @@ fun MetadataType.toXmlString(): String = """ ${this.authorName} -""".trim() +""".trim().removeEmptyStrings() -private fun now(clock: Clock?) = OffsetDateTime.now(clock ?: Clock.systemDefaultZone()).format(DTF) - -fun WptType.toXmlString(nodeName: String? = null) = - if (nodeName != null) { - this.toXmlString(nodeName) - } else { - this.toXmlString("wpt") - } +fun WptType.toXmlString(nodeName: String? = null) = if (nodeName != null) { + this.toXmlString(nodeName) +} else { + this.toXmlString("wpt") +} @JvmName("toXmlStringNamed") fun WptType.toXmlString(nodeName: String) = """ @@ -135,19 +132,19 @@ fun WptType.toXmlString(nodeName: String) = """ ${toXmlString(cmt, "cmt")} ${toXmlString(desc, "desc")} ${toXmlString(src, "src")} - ${link?.toXmlString()} + ${link?.toXmlString() ?: ""} ${toXmlString(sym, "sym")} ${toXmlString(type, "type")} - ${fix?.toXmlString()} + ${fix?.toXmlString() ?: ""} ${toXmlString(sat, "sat")} ${toXmlString(hdop, "hdop")} ${toXmlString(vdop, "vdop")} ${toXmlString(pdop, "pdop")} ${toXmlString(ageofgpsdata, "ageofgpsdata")} ${toXmlString(dgpsid, "dgpsid")} - ${extensions?.toXmlString()} + ${extensions?.toXmlString() ?: ""} -""".trim() +""".trim().removeEmptyStrings() fun RteType.toXmlString() = """ @@ -155,13 +152,13 @@ fun RteType.toXmlString() = """ ${toXmlString(this.cmt, "cmt")} ${toXmlString(this.desc, "desc")} ${toXmlString(this.src, "src")} - ${this.link?.toXmlString()} + ${this.link?.toXmlString() ?: ""} ${toXmlString(this.number, "number")} ${toXmlString(this.type, "type")} - ${this.extensions?.toXmlString()} - ${this.rtept?.toXmlString()} + ${this.extensions?.toXmlString() ?: ""} + ${this.rtept?.toXmlString() ?: ""} -""".trim() +""".trim().removeEmptyStrings() fun TrkType.toXmlString() = """ @@ -169,24 +166,47 @@ fun TrkType.toXmlString() = """ ${toXmlString(this.cmt, "cmt")} ${toXmlString(this.desc, "desc")} ${toXmlString(this.src, "src")} - ${this.link?.toXmlString()} + ${this.link?.toXmlString() ?: ""} ${toXmlString(this.number, "number")} ${toXmlString(this.type, "type")} - ${this.extensions?.toXmlString()} - ${this.trkseg?.toXmlString()} + ${this.extensions?.toXmlString() ?: ""} + ${this.trkseg?.toXmlString() ?: ""} -""".trim() +""".trim().removeEmptyStrings() -fun List.toXmlString(nodeName: String?) = - this.joinToString(prefix = "", postfix = "", separator = "") { - it.toXmlString(nodeName) - } +fun LinkType.toXmlString() = """ + + ${this.text} + ${this.type} + +""".trim().removeEmptyStrings() + +fun FixType.toXmlString() = """ + ${this.value} +""".trim().removeEmptyStrings() + +fun ExtensionType.toXmlString() = """ + <${this.nodeName}${toXmlString(this.parameters)}>${this.value ?: ""} + """.trim().removeEmptyStrings() + +fun TrksegType.toXmlString() = """ + + ${this.trkpt?.toXmlString("trkpt") ?: ""} + +""".trim().removeEmptyStrings() + +fun List.toXmlString(nodeName: String?) = this.joinToString(prefix = "\n", postfix = "", separator = "") { + it.toXmlString(nodeName) +} + +fun List.toXmlString() = this.joinToString( + prefix = "\n", postfix = "\n", separator = "\n", transform = ExtensionType::toXmlString +) @JvmName("toXmlStringWptType") -fun List.toXmlString() = - this.joinToString(prefix = "", postfix = "", separator = "") { - it.toXmlString() - } +fun List.toXmlString() = this.joinToString(prefix = "", postfix = "", separator = "") { + it.toXmlString() +} @JvmName("toXmlStringLinkType") fun List.toXmlString() = @@ -204,75 +224,41 @@ fun List.toXmlString() = fun List.toXmlString() = this.joinToString(prefix = "", postfix = "", separator = "", transform = TrksegType::toXmlString) -fun List.toXmlString() = - this.joinToString( - prefix = "\n", - postfix = "\n", - separator = "\n", - transform = ExtensionType::toXmlString - ) +fun toXmlString(value: String?, nodeName: String) = if (value != null) { + "<${nodeName}>${value}" +} else { + "" +} -fun LinkType.toXmlString() = """ - - ${this.text} - ${this.type} - -""".trim() +fun toXmlString(value: Int?, nodeName: String) = if (value != null) { + "<${nodeName}>${value}" +} else { + "" +} -fun FixType.toXmlString() = """ - ${this.value} -""".trim() +fun toXmlString(value: Double?, nodeName: String) = if (value != null) { + "<${nodeName}>${value}" +} else { + "" +} -fun ExtensionType.toXmlString() = """ - <${this.nodeName}${toXmlString(this.parameters)}>${this.value ?: ""} - """.trim() +fun toXmlString(value: OffsetDateTime?, nodeName: String) = if (value != null) { + "<${nodeName}>${value.format(DTF)}" +} else { + "" +} -fun TrksegType.toXmlString() = """ - - ${this.trkpt?.toXmlString("trkpt")} - -""".trim() +fun toXmlString(value: Map?) = value?.entries?.joinToString(separator = "") { + " ${it.key}=\"${it.value}\"" +} ?: "" -fun toXmlString(value: String?, nodeName: String) = - if (value != null) { - """ - <${nodeName}>${value} - """.trim() - } else { - "" - } +private fun now(clock: Clock?) = OffsetDateTime.now(clock ?: Clock.systemDefaultZone()).format(DTF) -fun toXmlString(value: Int?, nodeName: String) = - if (value != null) { - """ - <${nodeName}>${value} - """.trim() - } else { - "" - } - -fun toXmlString(value: Double?, nodeName: String) = - if (value != null) { - """ - <${nodeName}>${value} - """.trim() - } else { - "" - } - -fun toXmlString(value: OffsetDateTime?, nodeName: String) = - if (value != null) { - """ - <${nodeName}>${value.format(DTF)} - """.trim() - } else { - "" - } - -fun toXmlString(value: Map?) = - value?.entries?.joinToString(separator = "") { - " ${it.key}=\"${it.value}\"" - } ?: "" +private fun String.removeEmptyStrings() = this.lineSequence().map { + it.trim() +}.filter { + it != "" +}.joinToString("\n") class GpxWriter { companion object { @@ -281,9 +267,9 @@ class GpxWriter { const val XMLNS_XSI = "http://www.w3.org/2001/XMLSchema-instance" const val SCHEMA_LOCATION = "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" - internal val DTF = DateTimeFormatterBuilder() - .append(ISO_LOCAL_DATE_TIME) // use the existing formatter for date time - .appendOffset("+HH:MM", "+00:00") // set 'noOffsetText' to desired '+00:00' - .toFormatter() + internal val DTF = + DateTimeFormatterBuilder().append(ISO_LOCAL_DATE_TIME) // use the existing formatter for date time + .appendOffset("+HH:MM", "+00:00") // set 'noOffsetText' to desired '+00:00' + .toFormatter() } } diff --git a/src/test/kotlin/me/bvn13/sdk/android/gpx/GpxWriterTest.kt b/src/test/kotlin/me/bvn13/sdk/android/gpx/GpxWriterTest.kt index 6bd5caa..ce1807e 100644 --- a/src/test/kotlin/me/bvn13/sdk/android/gpx/GpxWriterTest.kt +++ b/src/test/kotlin/me/bvn13/sdk/android/gpx/GpxWriterTest.kt @@ -59,7 +59,7 @@ APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. -Copyright [yyyy] [name of copyright owner] +Copyright bvn13, 2022 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -77,184 +77,246 @@ limitations under the License. package me.bvn13.sdk.android.gpx -import io.kotest.core.spec.style.FunSpec +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test import java.time.* import kotlin.test.assertEquals -class GpxWriterTest : FunSpec() { - init { - test("first test") { - val clock = Clock.fixed( - LocalDateTime.of(2022, 9, 24, 15, 4, 0, 0).toInstant(ZoneOffset.ofHours(3)), ZoneId.of("Europe/Moscow") - ) +class GpxWriterTest { + @DisplayName("test minimum") + @Test + fun testMinimum() { + val clock = Clock.fixed( + LocalDateTime.of(2022, 9, 24, 15, 4, 0, 0).toInstant(ZoneOffset.ofHours(3)), ZoneId.of("Europe/Moscow") + ) - val gpxType = GpxType( - MetadataType("test name", description = "test description", authorName = "bvn13"), - wpt = listOf( - WptType( - lat = 14.64736838389662, - lon = 7.93212890625, - ele = 10.toDouble(), - time = OffsetDateTime.now(clock), - magvar = 3.toDouble(), - geoidheight = 45.toDouble(), - name = "test point 1", - cmt = "comment 1", - desc = "description of point 1", - link = listOf( - LinkType( - href = "http://link-to.site.href", - text = "text", - type = "hyperlink" - ), - LinkType( - href = "http://link2-to.site.href", - text = "text2", - type = "hyperlink2" - ) - ), - src = "source 1", - sym = "sym 1", - type = "type 1", - fix = FixType.DGPS, - sat = 1, - hdop = 55.toDouble(), - vdop = 66.toDouble(), - pdop = 77.toDouble(), - ageofgpsdata = 44, - dgpsid = 88, - extensions = listOf( - ExtensionType( - "extension1", - parameters = mapOf(Pair("first", "second"), Pair("third", "fours")) - ), - ExtensionType( - "extension2", - parameters = mapOf(Pair("aa", "bb"), Pair("cc", "dd")) - ) - ) - ) - ), - rte = listOf( - RteType( - name = "rte name", - cmt = "cmt", - desc = "desc", - src = "src", - link = listOf( - LinkType( - href = "https://new.link.rte", - text = "new text rte", - type = "hyperlink" - ) - ), - number = 1234, - type = "route", - extensions = listOf( - ExtensionType( - "ext-1", - value = "value1" - ) - ), - rtept = listOf( - WptType( - lat = 14.64736838389662, - lon = 7.93212890625, - ele = 10.toDouble(), - time = OffsetDateTime.now(clock), - magvar = 3.toDouble(), - geoidheight = 45.toDouble(), - name = "test point 1", - cmt = "comment 1", - desc = "description of point 1", - link = listOf( - LinkType( - href = "http://link-to.site.href", - text = "text", - type = "hyperlink" - ), - LinkType( - href = "http://link2-to.site.href", - text = "text2", - type = "hyperlink2" - ) - ), - src = "source 1", - sym = "sym 1", - type = "type 1", - fix = FixType.DGPS, - sat = 1, - hdop = 55.toDouble(), - vdop = 66.toDouble(), - pdop = 77.toDouble(), - ageofgpsdata = 44, - dgpsid = 88, - extensions = listOf( - ExtensionType( - "extension1", - parameters = mapOf(Pair("first", "second"), Pair("third", "fours")) - ), - ExtensionType( - "extension2", - parameters = mapOf(Pair("aa", "bb"), Pair("cc", "dd")) - ) + val gpxType = GpxType( + MetadataType("test name"), + trk = listOf( + TrkType( + name = "track1", + trkseg = listOf( + TrksegType( + listOf( + WptType( + lat = 123.toDouble(), + lon = 321.toDouble() ) ) ) ) - ), - trk = listOf( - TrkType( - name = "track 1", - cmt = "comment track 1", - desc = "desc track 1", - src = "src track 1", - number = 1234, - type = "type 1", - trkseg = listOf( - TrksegType( - listOf( - WptType( - lat = 14.64736838389662, - lon = 7.93212890625, - ele = 10.toDouble(), - time = OffsetDateTime.now(clock), - magvar = 3.toDouble(), - geoidheight = 45.toDouble(), - name = "test point 1", - cmt = "comment 1", - desc = "description of point 1", - link = listOf( - LinkType( - href = "http://link-to.site.href", - text = "text", - type = "hyperlink" - ), - LinkType( - href = "http://link2-to.site.href", - text = "text2", - type = "hyperlink2" - ) + ) + ) + ) + + assertEquals( + """ + + + + + test name + + + + + + + track1 + + + + + + + """.trim() + .lineSequence() + .map { + it.trim() + } + .joinToString("\n"), + gpxType.toXmlString(clock) + ) + } + + @DisplayName("test maximum") + @Test + fun maximumTest() { + val clock = Clock.fixed( + LocalDateTime.of(2022, 9, 24, 15, 4, 0, 0).toInstant(ZoneOffset.ofHours(3)), ZoneId.of("Europe/Moscow") + ) + + val gpxType = GpxType( + MetadataType("test name", description = "test description", authorName = "bvn13"), + wpt = listOf( + WptType( + lat = 14.64736838389662, + lon = 7.93212890625, + ele = 10.toDouble(), + time = OffsetDateTime.now(clock), + magvar = 3.toDouble(), + geoidheight = 45.toDouble(), + name = "test point 1", + cmt = "comment 1", + desc = "description of point 1", + link = listOf( + LinkType( + href = "http://link-to.site.href", + text = "text", + type = "hyperlink" + ), + LinkType( + href = "http://link2-to.site.href", + text = "text2", + type = "hyperlink2" + ) + ), + src = "source 1", + sym = "sym 1", + type = "type 1", + fix = FixType.DGPS, + sat = 1, + hdop = 55.toDouble(), + vdop = 66.toDouble(), + pdop = 77.toDouble(), + ageofgpsdata = 44, + dgpsid = 88, + extensions = listOf( + ExtensionType( + "extension1", + parameters = mapOf(Pair("first", "second"), Pair("third", "fours")) + ), + ExtensionType( + "extension2", + parameters = mapOf(Pair("aa", "bb"), Pair("cc", "dd")) + ) + ) + ) + ), + rte = listOf( + RteType( + name = "rte name", + cmt = "cmt", + desc = "desc", + src = "src", + link = listOf( + LinkType( + href = "https://new.link.rte", + text = "new text rte", + type = "hyperlink" + ) + ), + number = 1234, + type = "route", + extensions = listOf( + ExtensionType( + "ext-1", + value = "value1" + ) + ), + rtept = listOf( + WptType( + lat = 14.64736838389662, + lon = 7.93212890625, + ele = 10.toDouble(), + time = OffsetDateTime.now(clock), + magvar = 3.toDouble(), + geoidheight = 45.toDouble(), + name = "test point 1", + cmt = "comment 1", + desc = "description of point 1", + link = listOf( + LinkType( + href = "http://link-to.site.href", + text = "text", + type = "hyperlink" + ), + LinkType( + href = "http://link2-to.site.href", + text = "text2", + type = "hyperlink2" + ) + ), + src = "source 1", + sym = "sym 1", + type = "type 1", + fix = FixType.DGPS, + sat = 1, + hdop = 55.toDouble(), + vdop = 66.toDouble(), + pdop = 77.toDouble(), + ageofgpsdata = 44, + dgpsid = 88, + extensions = listOf( + ExtensionType( + "extension1", + parameters = mapOf(Pair("first", "second"), Pair("third", "fours")) + ), + ExtensionType( + "extension2", + parameters = mapOf(Pair("aa", "bb"), Pair("cc", "dd")) + ) + ) + ) + ) + ) + ), + trk = listOf( + TrkType( + name = "track 1", + cmt = "comment track 1", + desc = "desc track 1", + src = "src track 1", + number = 1234, + type = "type 1", + trkseg = listOf( + TrksegType( + listOf( + WptType( + lat = 14.64736838389662, + lon = 7.93212890625, + ele = 10.toDouble(), + time = OffsetDateTime.now(clock), + magvar = 3.toDouble(), + geoidheight = 45.toDouble(), + name = "test point 1", + cmt = "comment 1", + desc = "description of point 1", + link = listOf( + LinkType( + href = "http://link-to.site.href", + text = "text", + type = "hyperlink" ), - src = "source 1", - sym = "sym 1", - type = "type 1", - fix = FixType.DGPS, - sat = 1, - hdop = 55.toDouble(), - vdop = 66.toDouble(), - pdop = 77.toDouble(), - ageofgpsdata = 44, - dgpsid = 88, - extensions = listOf( - ExtensionType( - "extension1", - parameters = mapOf(Pair("first", "second"), Pair("third", "fours")) - ), - ExtensionType( - "extension2", - parameters = mapOf(Pair("aa", "bb"), Pair("cc", "dd")) - ) + LinkType( + href = "http://link2-to.site.href", + text = "text2", + type = "hyperlink2" + ) + ), + src = "source 1", + sym = "sym 1", + type = "type 1", + fix = FixType.DGPS, + sat = 1, + hdop = 55.toDouble(), + vdop = 66.toDouble(), + pdop = 77.toDouble(), + ageofgpsdata = 44, + dgpsid = 88, + extensions = listOf( + ExtensionType( + "extension1", + parameters = mapOf(Pair("first", "second"), Pair("third", "fours")) + ), + ExtensionType( + "extension2", + parameters = mapOf(Pair("aa", "bb"), Pair("cc", "dd")) ) ) ) @@ -263,148 +325,151 @@ class GpxWriterTest : FunSpec() { ) ) ) + ) - assertEquals( - """ - - - - - test name - test description - - bvn13 - - - - 10.0 - - 3.0 - 45.0 - test point 1 - comment 1 - description of point 1 - source 1 - - text - hyperlink - - - text2 - hyperlink2 - - sym 1 - type 1 - dgps - 1 - 55.0 - 66.0 - 77.0 - 44 - 88 - - - - - - - rte name - cmt - desc - src - - new text rte - hyperlink - - 1234 - route - -value1 - - - 10.0 - - 3.0 - 45.0 - test point 1 - comment 1 - description of point 1 - source 1 - - text - hyperlink - - - text2 - hyperlink2 - - sym 1 - type 1 - dgps - 1 - 55.0 - 66.0 - 77.0 - 44 - 88 - - - - - - - - track 1 - comment track 1 - desc track 1 - src track 1 - null - 1234 - type 1 - null - - - 10.0 - - 3.0 - 45.0 - test point 1 - comment 1 - description of point 1 - source 1 - - text - hyperlink - - - text2 - hyperlink2 - - sym 1 - type 1 - dgps - 1 - 55.0 - 66.0 - 77.0 - 44 - 88 - - - - - - - - - """.trim(), - gpxType.toXmlString(clock) - ) - } + assertEquals( + """ + + + + + test name + test description + + bvn13 + + + + 10.0 + + 3.0 + 45.0 + test point 1 + comment 1 + description of point 1 + source 1 + + text + hyperlink + + + text2 + hyperlink2 + + sym 1 + type 1 + dgps + 1 + 55.0 + 66.0 + 77.0 + 44 + 88 + + + + + + + rte name + cmt + desc + src + + new text rte + hyperlink + + 1234 + route + + value1 + + + 10.0 + + 3.0 + 45.0 + test point 1 + comment 1 + description of point 1 + source 1 + + text + hyperlink + + + text2 + hyperlink2 + + sym 1 + type 1 + dgps + 1 + 55.0 + 66.0 + 77.0 + 44 + 88 + + + + + + + + track 1 + comment track 1 + desc track 1 + src track 1 + 1234 + type 1 + + + 10.0 + + 3.0 + 45.0 + test point 1 + comment 1 + description of point 1 + source 1 + + text + hyperlink + + + text2 + hyperlink2 + + sym 1 + type 1 + dgps + 1 + 55.0 + 66.0 + 77.0 + 44 + 88 + + + + + + + + + """.trim() + .lineSequence() + .map { + it.trim() + } + .joinToString("\n"), + gpxType.toXmlString(clock) + ) } } \ No newline at end of file From 2beef609c1199e30c73d90cad97c660db8c86695 Mon Sep 17 00:00:00 2001 From: bvn13 Date: Thu, 29 Sep 2022 19:36:03 +0300 Subject: [PATCH 3/3] Update versions for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 94c474c..3d7f397 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ GpxAndroidSdk me.bvn13.sdk.android.gpx - 1.2-SNAPSHOT + 1.2 jar