Merge commit 'a41f2c38ec9683f0e9aaca3e4cffb2cd45f21145' into less_memory_test_branch

This commit is contained in:
Vitor Pamplona
2023-03-08 17:34:40 -05:00
10 changed files with 121 additions and 116 deletions

View File

@@ -3,9 +3,7 @@ package com.vitorpamplona.amethyst.service.model
import android.util.Log import android.util.Log
import com.vitorpamplona.amethyst.model.toByteArray import com.vitorpamplona.amethyst.model.toByteArray
import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.model.toHexKey
import com.vitorpamplona.amethyst.service.NIP19TLVTypes import com.vitorpamplona.amethyst.service.nip19.Tlv
import com.vitorpamplona.amethyst.service.parseTLV
import com.vitorpamplona.amethyst.service.toInt32
import fr.acinq.secp256k1.Hex import fr.acinq.secp256k1.Hex
import nostr.postr.Bech32 import nostr.postr.Bech32
import nostr.postr.bechToBytes import nostr.postr.bechToBytes
@@ -20,16 +18,15 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela
val dTag = dTag.toByteArray(Charsets.UTF_8) val dTag = dTag.toByteArray(Charsets.UTF_8)
val relay = relay?.toByteArray(Charsets.UTF_8) val relay = relay?.toByteArray(Charsets.UTF_8)
var fullArray = var fullArray = byteArrayOf(Tlv.Type.SPECIAL.id, dTag.size.toByte()) + dTag
byteArrayOf(NIP19TLVTypes.SPECIAL.id, dTag.size.toByte()) + dTag
if (relay != null) { if (relay != null) {
fullArray = fullArray + byteArrayOf(NIP19TLVTypes.RELAY.id, relay.size.toByte()) + relay fullArray = fullArray + byteArrayOf(Tlv.Type.RELAY.id, relay.size.toByte()) + relay
} }
fullArray = fullArray + fullArray = fullArray +
byteArrayOf(NIP19TLVTypes.AUTHOR.id, author.size.toByte()) + author + byteArrayOf(Tlv.Type.AUTHOR.id, author.size.toByte()) + author +
byteArrayOf(NIP19TLVTypes.KIND.id, kind.size.toByte()) + kind byteArrayOf(Tlv.Type.KIND.id, kind.size.toByte()) + kind
return Bech32.encodeBytes(hrp = "naddr", fullArray, Bech32.Encoding.Bech32) return Bech32.encodeBytes(hrp = "naddr", fullArray, Bech32.Encoding.Bech32)
} }
@@ -63,11 +60,11 @@ data class ATag(val kind: Int, val pubKeyHex: String, val dTag: String, val rela
val key = naddr.removePrefix("nostr:") val key = naddr.removePrefix("nostr:")
if (key.startsWith("naddr")) { if (key.startsWith("naddr")) {
val tlv = parseTLV(key.bechToBytes()) val tlv = Tlv.parse(key.bechToBytes())
val d = tlv.get(NIP19TLVTypes.SPECIAL.id)?.get(0)?.toString(Charsets.UTF_8) ?: "" val d = tlv.get(Tlv.Type.SPECIAL.id)?.get(0)?.toString(Charsets.UTF_8) ?: ""
val relay = tlv.get(NIP19TLVTypes.RELAY.id)?.get(0)?.toString(Charsets.UTF_8) val relay = tlv.get(Tlv.Type.RELAY.id)?.get(0)?.toString(Charsets.UTF_8)
val author = tlv.get(NIP19TLVTypes.AUTHOR.id)?.get(0)?.toHexKey() val author = tlv.get(Tlv.Type.AUTHOR.id)?.get(0)?.toHexKey()
val kind = tlv.get(NIP19TLVTypes.KIND.id)?.get(0)?.let { toInt32(it) } val kind = tlv.get(Tlv.Type.KIND.id)?.get(0)?.let { Tlv.toInt32(it) }
if (kind != null && author != null) { if (kind != null && author != null) {
return ATag(kind, author, d, relay) return ATag(kind, author, d, relay)

View File

@@ -1,17 +1,14 @@
package com.vitorpamplona.amethyst.service package com.vitorpamplona.amethyst.service.nip19
import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.model.toHexKey
import nostr.postr.bechToBytes import nostr.postr.bechToBytes
import java.nio.ByteBuffer
import java.nio.ByteOrder
class Nip19 {
object Nip19 {
enum class Type { enum class Type {
USER, NOTE, RELAY, ADDRESS USER, NOTE, RELAY, ADDRESS
} }
data class Return(val type: Type, val hex: String, val relay: String?) data class Return(val type: Type, val hex: String, val relay: String? = null)
fun uriToRoute(uri: String?): Return? { fun uriToRoute(uri: String?): Return? {
try { try {
@@ -39,21 +36,21 @@ class Nip19 {
} }
private fun npub(bytes: ByteArray): Return { private fun npub(bytes: ByteArray): Return {
return Return(Type.USER, bytes.toHexKey(), null) return Return(Type.USER, bytes.toHexKey())
} }
private fun note(bytes: ByteArray): Return { private fun note(bytes: ByteArray): Return {
return Return(Type.NOTE, bytes.toHexKey(), null) return Return(Type.NOTE, bytes.toHexKey())
} }
private fun nprofile(bytes: ByteArray): Return? { private fun nprofile(bytes: ByteArray): Return? {
val tlv = parseTLV(bytes) val tlv = Tlv.parse(bytes)
val hex = tlv.get(NIP19TLVTypes.SPECIAL.id) val hex = tlv.get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toHexKey() ?: return null ?.toHexKey() ?: return null
val relay = tlv.get(NIP19TLVTypes.RELAY.id) val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?.toString(Charsets.UTF_8)
@@ -61,13 +58,13 @@ class Nip19 {
} }
private fun nevent(bytes: ByteArray): Return? { private fun nevent(bytes: ByteArray): Return? {
val tlv = parseTLV(bytes) val tlv = Tlv.parse(bytes)
val hex = tlv.get(NIP19TLVTypes.SPECIAL.id) val hex = tlv.get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toHexKey() ?: return null ?.toHexKey() ?: return null
val relay = tlv.get(NIP19TLVTypes.RELAY.id) val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?.toString(Charsets.UTF_8)
@@ -75,64 +72,33 @@ class Nip19 {
} }
private fun nrelay(bytes: ByteArray): Return? { private fun nrelay(bytes: ByteArray): Return? {
val relayUrl = parseTLV(bytes) val relayUrl = Tlv.parse(bytes)
.get(NIP19TLVTypes.SPECIAL.id) .get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?: return null ?.toString(Charsets.UTF_8) ?: return null
return Return(Type.RELAY, relayUrl, null) return Return(Type.RELAY, relayUrl)
} }
private fun naddr(bytes: ByteArray): Return? { private fun naddr(bytes: ByteArray): Return? {
val tlv = parseTLV(bytes) val tlv = Tlv.parse(bytes)
val d = tlv.get(NIP19TLVTypes.SPECIAL.id) val d = tlv.get(Tlv.Type.SPECIAL.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?: return null ?.toString(Charsets.UTF_8) ?: return null
val relay = tlv.get(NIP19TLVTypes.RELAY.id) val relay = tlv.get(Tlv.Type.RELAY.id)
?.get(0) ?.get(0)
?.toString(Charsets.UTF_8) ?.toString(Charsets.UTF_8)
val author = tlv.get(NIP19TLVTypes.AUTHOR.id) val author = tlv.get(Tlv.Type.AUTHOR.id)
?.get(0) ?.get(0)
?.toHexKey() ?.toHexKey()
val kind = tlv.get(NIP19TLVTypes.KIND.id) val kind = tlv.get(Tlv.Type.KIND.id)
?.get(0) ?.get(0)
?.let { toInt32(it) } ?.let { Tlv.toInt32(it) }
return Return(Type.ADDRESS, "$kind:$author:$d", relay) return Return(Type.ADDRESS, "$kind:$author:$d", relay)
} }
} }
// Classes should start with an uppercase letter in kotlin
enum class NIP19TLVTypes(val id: Byte) {
SPECIAL(0),
RELAY(1),
AUTHOR(2),
KIND(3);
}
fun toInt32(bytes: ByteArray): Int {
require(bytes.size == 4) { "length must be 4, got: ${bytes.size}" }
return ByteBuffer.wrap(bytes, 0, 4).order(ByteOrder.BIG_ENDIAN).int
}
fun parseTLV(data: ByteArray): Map<Byte, List<ByteArray>> {
val result = mutableMapOf<Byte, MutableList<ByteArray>>()
var rest = data
while (rest.isNotEmpty()) {
val t = rest[0]
val l = rest[1]
val v = rest.sliceArray(IntRange(2, (2 + l) - 1))
rest = rest.sliceArray(IntRange(2 + l, rest.size - 1))
if (v.size < l) continue
if (!result.containsKey(t)) {
result[t] = mutableListOf()
}
result[t]?.add(v)
}
return result
}

View File

@@ -0,0 +1,36 @@
package com.vitorpamplona.amethyst.service.nip19
import java.nio.ByteBuffer
import java.nio.ByteOrder
object Tlv {
enum class Type(val id: Byte) {
SPECIAL(0),
RELAY(1),
AUTHOR(2),
KIND(3);
}
fun toInt32(bytes: ByteArray): Int {
require(bytes.size == 4) { "length must be 4, got: ${bytes.size}" }
return ByteBuffer.wrap(bytes, 0, 4).order(ByteOrder.BIG_ENDIAN).int
}
fun parse(data: ByteArray): Map<Byte, List<ByteArray>> {
val result = mutableMapOf<Byte, MutableList<ByteArray>>()
var rest = data
while (rest.isNotEmpty()) {
val t = rest[0]
val l = rest[1]
val v = rest.sliceArray(IntRange(2, (2 + l) - 1))
rest = rest.sliceArray(IntRange(2 + l, rest.size - 1))
if (v.size < l) continue
if (!result.containsKey(t)) {
result[t] = mutableListOf()
}
result[t]?.add(v)
}
return result
}
}

View File

@@ -16,7 +16,7 @@ import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder import coil.decode.SvgDecoder
import com.vitorpamplona.amethyst.LocalPreferences import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.service.Nip19 import com.vitorpamplona.amethyst.service.nip19.Nip19
import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.screen.AccountScreen import com.vitorpamplona.amethyst.ui.screen.AccountScreen
import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel
@@ -26,7 +26,7 @@ class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val nip19 = Nip19().uriToRoute(intent?.data?.toString()) val nip19 = Nip19.uriToRoute(intent?.data?.toString())
val startingPage = when (nip19?.type) { val startingPage = when (nip19?.type) {
Nip19.Type.USER -> "User/${nip19.hex}" Nip19.Type.USER -> "User/${nip19.hex}"
Nip19.Type.NOTE -> "Note/${nip19.hex}" Nip19.Type.NOTE -> "Note/${nip19.hex}"

View File

@@ -10,8 +10,8 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.navigation.NavController import androidx.navigation.NavController
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.Nip19
import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent import com.vitorpamplona.amethyst.service.model.ChannelCreateEvent
import com.vitorpamplona.amethyst.service.nip19.Nip19
@Composable @Composable
fun ClickableRoute( fun ClickableRoute(

View File

@@ -12,9 +12,7 @@ import androidx.compose.material.LocalTextStyle
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@@ -34,8 +32,8 @@ import com.halilibo.richtext.ui.RichTextStyle
import com.halilibo.richtext.ui.material.MaterialRichText import com.halilibo.richtext.ui.material.MaterialRichText
import com.halilibo.richtext.ui.resolveDefaults import com.halilibo.richtext.ui.resolveDefaults
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.Nip19
import com.vitorpamplona.amethyst.service.lnurl.LnInvoiceUtil import com.vitorpamplona.amethyst.service.lnurl.LnInvoiceUtil
import com.vitorpamplona.amethyst.service.nip19.Nip19
import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.NoteCompose
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import java.net.MalformedURLException import java.net.MalformedURLException
@@ -210,7 +208,7 @@ fun BechLink(word: String, navController: NavController) {
} }
val nip19Route = try { val nip19Route = try {
Nip19().uriToRoute(uri) Nip19.uriToRoute(uri)
} catch (e: Exception) { } catch (e: Exception) {
null null
} }

View File

@@ -21,7 +21,7 @@ import com.google.mlkit.vision.barcode.BarcodeScannerOptions
import com.google.mlkit.vision.barcode.BarcodeScanning import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.barcode.common.Barcode import com.google.mlkit.vision.barcode.common.Barcode
import com.google.mlkit.vision.common.InputImage import com.google.mlkit.vision.common.InputImage
import com.vitorpamplona.amethyst.service.Nip19 import com.vitorpamplona.amethyst.service.nip19.Nip19
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors import java.util.concurrent.Executors
@@ -52,7 +52,7 @@ fun QrCodeScanner(onScan: (String) -> Unit) {
val analyzer = QRCodeAnalyzer { result -> val analyzer = QRCodeAnalyzer { result ->
result?.let { result?.let {
try { try {
val nip19 = Nip19().uriToRoute(it) val nip19 = Nip19.uriToRoute(it)
val startingPage = when (nip19?.type) { val startingPage = when (nip19?.type) {
Nip19.Type.USER -> "User/${nip19.hex}" Nip19.Type.USER -> "User/${nip19.hex}"
Nip19.Type.NOTE -> "Note/${nip19.hex}" Nip19.Type.NOTE -> "Note/${nip19.hex}"

View File

@@ -1,26 +1,26 @@
package com.vitorpamplona.amethyst package com.vitorpamplona.amethyst
import com.vitorpamplona.amethyst.service.Nip19
import com.vitorpamplona.amethyst.service.model.ATag import com.vitorpamplona.amethyst.service.model.ATag
import com.vitorpamplona.amethyst.service.nip19.Nip19
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class NIP19ParserTest { class NIP19ParserTest {
@Test @Test
fun nAddrParser() { fun nAddrParser() {
val result = Nip19().uriToRoute("nostr:naddr1qqqqygzxpsj7dqha57pjk5k37gkn6g4nzakewtmqmnwryyhd3jfwlpgxtspsgqqqw4rs3xyxus") val result = Nip19.uriToRoute("nostr:naddr1qqqqygzxpsj7dqha57pjk5k37gkn6g4nzakewtmqmnwryyhd3jfwlpgxtspsgqqqw4rs3xyxus")
assertEquals("30023:460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c:", result?.hex) assertEquals("30023:460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c:", result?.hex)
} }
@Test @Test
fun nAddrParser2() { fun nAddrParser2() {
val result = Nip19().uriToRoute("nostr:naddr1qq8kwatfv3jj6amfwfjkwatpwfjqygxsm6lelvfda7qlg0tud9pfhduysy4vrexj65azqtdk4tr75j6xdspsgqqqw4rsg32ag8") val result = Nip19.uriToRoute("nostr:naddr1qq8kwatfv3jj6amfwfjkwatpwfjqygxsm6lelvfda7qlg0tud9pfhduysy4vrexj65azqtdk4tr75j6xdspsgqqqw4rsg32ag8")
assertEquals("30023:d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c:guide-wireguard", result?.hex) assertEquals("30023:d0debf9fb12def81f43d7c69429bb784812ac1e4d2d53a202db6aac7ea4b466c:guide-wireguard", result?.hex)
} }
@Test @Test
fun nAddrParse3() { fun nAddrParse3() {
val result = Nip19().uriToRoute("naddr1qqyrswtyv5mnjv3sqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygx3uczxts4hwue9ayfn7ggq62anzstde2qs749pm9tx2csuthhpjvpsgqqqw4rs8pmj38") val result = Nip19.uriToRoute("naddr1qqyrswtyv5mnjv3sqy28wumn8ghj7un9d3shjtnyv9kh2uewd9hsygx3uczxts4hwue9ayfn7ggq62anzstde2qs749pm9tx2csuthhpjvpsgqqqw4rs8pmj38")
assertEquals(Nip19.Type.ADDRESS, result?.type) assertEquals(Nip19.Type.ADDRESS, result?.type)
assertEquals("30023:d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193:89de7920", result?.hex) assertEquals("30023:d1e60465c2b777325e9133f2100d2bb31416dca810f54a1d95665621c5dee193:89de7920", result?.hex)
assertEquals("wss://relay.damus.io", result?.relay) assertEquals("wss://relay.damus.io", result?.relay)

View File

@@ -1,46 +1,21 @@
package com.vitorpamplona.amethyst.service package com.vitorpamplona.amethyst.service
import com.vitorpamplona.amethyst.service.nip19.Nip19
import org.junit.Assert import org.junit.Assert
import org.junit.Ignore import org.junit.Ignore
import org.junit.Test import org.junit.Test
class Nip19Test { class Nip19Test {
private val nip19 = Nip19()
@Test(expected = IllegalArgumentException::class)
fun to_int_32_length_smaller_than_4() {
toInt32(byteArrayOfInts(1, 2, 3))
}
@Test(expected = IllegalArgumentException::class)
fun to_int_32_length_bigger_than_4() {
toInt32(byteArrayOfInts(1, 2, 3, 4, 5))
}
@Test()
fun to_int_32_length_4() {
val actual = toInt32(byteArrayOfInts(1, 2, 3, 4))
Assert.assertEquals(16909060, actual)
}
@Ignore("Test not implemented yet")
@Test()
fun parse_TLV() {
// TODO: I don't know how to test this (?)
}
@Test() @Test()
fun uri_to_route_null() { fun uri_to_route_null() {
val actual = nip19.uriToRoute(null) val actual = Nip19.uriToRoute(null)
Assert.assertEquals(null, actual) Assert.assertEquals(null, actual)
} }
@Test() @Test()
fun uri_to_route_unknown() { fun uri_to_route_unknown() {
val actual = nip19.uriToRoute("nostr:unknown") val actual = Nip19.uriToRoute("nostr:unknown")
Assert.assertEquals(null, actual) Assert.assertEquals(null, actual)
} }
@@ -48,7 +23,7 @@ class Nip19Test {
@Test() @Test()
fun uri_to_route_npub() { fun uri_to_route_npub() {
val actual = val actual =
nip19.uriToRoute("nostr:npub1hv7k2s755n697sptva8vkh9jz40lzfzklnwj6ekewfmxp5crwdjs27007y") Nip19.uriToRoute("nostr:npub1hv7k2s755n697sptva8vkh9jz40lzfzklnwj6ekewfmxp5crwdjs27007y")
Assert.assertEquals(Nip19.Type.USER, actual?.type) Assert.assertEquals(Nip19.Type.USER, actual?.type)
Assert.assertEquals( Assert.assertEquals(
@@ -60,7 +35,7 @@ class Nip19Test {
@Test() @Test()
fun uri_to_route_note() { fun uri_to_route_note() {
val actual = val actual =
nip19.uriToRoute("nostr:note1stqea6wmwezg9x6yyr6qkukw95ewtdukyaztycws65l8wppjmtpscawevv") Nip19.uriToRoute("nostr:note1stqea6wmwezg9x6yyr6qkukw95ewtdukyaztycws65l8wppjmtpscawevv")
Assert.assertEquals(Nip19.Type.NOTE, actual?.type) Assert.assertEquals(Nip19.Type.NOTE, actual?.type)
Assert.assertEquals( Assert.assertEquals(
@@ -72,7 +47,7 @@ class Nip19Test {
@Ignore("Test not implemented yet") @Ignore("Test not implemented yet")
@Test() @Test()
fun uri_to_route_nprofile() { fun uri_to_route_nprofile() {
val actual = nip19.uriToRoute("nostr:nprofile") val actual = Nip19.uriToRoute("nostr:nprofile")
Assert.assertEquals(Nip19.Type.USER, actual?.type) Assert.assertEquals(Nip19.Type.USER, actual?.type)
Assert.assertEquals("*", actual?.hex) Assert.assertEquals("*", actual?.hex)
@@ -81,7 +56,7 @@ class Nip19Test {
@Ignore("Test not implemented yet") @Ignore("Test not implemented yet")
@Test() @Test()
fun uri_to_route_nevent() { fun uri_to_route_nevent() {
val actual = nip19.uriToRoute("nostr:nevent") val actual = Nip19.uriToRoute("nostr:nevent")
Assert.assertEquals(Nip19.Type.USER, actual?.type) Assert.assertEquals(Nip19.Type.USER, actual?.type)
Assert.assertEquals("*", actual?.hex) Assert.assertEquals("*", actual?.hex)
@@ -90,7 +65,7 @@ class Nip19Test {
@Ignore("Test not implemented yet") @Ignore("Test not implemented yet")
@Test() @Test()
fun uri_to_route_nrelay() { fun uri_to_route_nrelay() {
val actual = nip19.uriToRoute("nostr:nrelay") val actual = Nip19.uriToRoute("nostr:nrelay")
Assert.assertEquals(Nip19.Type.RELAY, actual?.type) Assert.assertEquals(Nip19.Type.RELAY, actual?.type)
Assert.assertEquals("*", actual?.hex) Assert.assertEquals("*", actual?.hex)
@@ -99,11 +74,9 @@ class Nip19Test {
@Ignore("Test not implemented yet") @Ignore("Test not implemented yet")
@Test() @Test()
fun uri_to_route_naddr() { fun uri_to_route_naddr() {
val actual = nip19.uriToRoute("nostr:naddr") val actual = Nip19.uriToRoute("nostr:naddr")
Assert.assertEquals(Nip19.Type.ADDRESS, actual?.type) Assert.assertEquals(Nip19.Type.ADDRESS, actual?.type)
Assert.assertEquals("*", actual?.hex) Assert.assertEquals("*", actual?.hex)
} }
private fun byteArrayOfInts(vararg ints: Int) = ByteArray(ints.size) { pos -> ints[pos].toByte() }
} }

View File

@@ -0,0 +1,35 @@
package com.vitorpamplona.amethyst.service
import com.vitorpamplona.amethyst.service.nip19.Tlv
import org.junit.Assert
import org.junit.Ignore
import org.junit.Test
class TlvTest {
@Test(expected = IllegalArgumentException::class)
fun to_int_32_length_smaller_than_4() {
Tlv.toInt32(byteArrayOfInts(1, 2, 3))
}
@Test(expected = IllegalArgumentException::class)
fun to_int_32_length_bigger_than_4() {
Tlv.toInt32(byteArrayOfInts(1, 2, 3, 4, 5))
}
@Test()
fun to_int_32_length_4() {
val actual = Tlv.toInt32(byteArrayOfInts(1, 2, 3, 4))
Assert.assertEquals(16909060, actual)
}
@Ignore("Test not implemented yet")
@Test()
fun parse_TLV() {
// TODO: I don't know how to test this (?)
}
private fun byteArrayOfInts(vararg ints: Int) =
ByteArray(ints.size) { pos -> ints[pos].toByte() }
}