mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-05 03:55:58 +01:00
Diabetes levels of DSL and sugar
This commit is contained in:
parent
9d6ae1c0bb
commit
11d868dc27
6 changed files with 254 additions and 22 deletions
|
@ -20,12 +20,6 @@ data class CertSynopsis(
|
|||
val revocationState: RevocationState = RevocationState.notRevoked(),
|
||||
val userIds : Map<String, RevocationState> = mapOf()) {
|
||||
|
||||
constructor(fingerprint: String,
|
||||
expirationTime: Date? = null,
|
||||
revocationState: RevocationState = RevocationState.notRevoked(),
|
||||
userIds: Map<String, RevocationState> = mapOf()):
|
||||
this(Fingerprint(fingerprint), expirationTime, revocationState, userIds)
|
||||
|
||||
override fun toString(): String {
|
||||
return if (userIds.isEmpty()) {
|
||||
"$fingerprint"
|
||||
|
|
|
@ -44,7 +44,7 @@ data class Certification(
|
|||
constructor(
|
||||
issuer: CertSynopsis,
|
||||
target: CertSynopsis,
|
||||
targetUserId: String?,
|
||||
targetUserId: String? = null,
|
||||
creationTime: Date) :
|
||||
this(issuer, target, targetUserId, creationTime, null, true, 120, Depth.limited(0), RegexSet.wildcard())
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ class Network(
|
|||
}
|
||||
|
||||
class Builder internal constructor() {
|
||||
private val nodes: MutableMap<Fingerprint, CertSynopsis> = mutableMapOf()
|
||||
val nodes: MutableMap<Fingerprint, CertSynopsis> = mutableMapOf()
|
||||
private val protoEdges: MutableMap<Pair<Fingerprint, Fingerprint>, CertificationSet> = mutableMapOf()
|
||||
private var referenceTime: ReferenceTime = ReferenceTime.now()
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class CertSynopsisTest: NetworkDSL {
|
||||
|
||||
@Test
|
||||
fun `Fingerprint 'A' toString`() {
|
||||
val node = CertSynopsis("A")
|
||||
assertEquals("A", node.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Fingerprint 'a' toString`() {
|
||||
val node = CertSynopsis("a")
|
||||
assertEquals("A", node.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Fingerprint 'A' and UserID toString`() {
|
||||
val node = CertSynopsis("A", "Alice <alice@example.org>")
|
||||
assertEquals("A (Alice <alice@example.org>)", node.toString())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.wot.dijkstra
|
||||
|
||||
import org.pgpainless.wot.dijkstra.sq.*
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Tons of useful DSL for [Network]-related testing.
|
||||
*/
|
||||
interface NetworkDSL {
|
||||
|
||||
/**
|
||||
* Create [CertSynopsis] from [String] fingerprint.
|
||||
*/
|
||||
fun CertSynopsis(fingerprint: String): CertSynopsis =
|
||||
CertSynopsis(Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf())
|
||||
|
||||
/**
|
||||
* Create [CertSynopsis] from [String] fingerprint and non-revoked [userId].
|
||||
*/
|
||||
fun CertSynopsis(fingerprint: String, userId: String): CertSynopsis = CertSynopsis(
|
||||
Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf(userId to RevocationState.notRevoked()))
|
||||
|
||||
fun CertSynopsis(original: CertSynopsis, userId: String): CertSynopsis = CertSynopsis(
|
||||
original.fingerprint, original.expirationTime, original.revocationState, original.userIds.plus(userId to RevocationState.notRevoked())
|
||||
)
|
||||
|
||||
/**
|
||||
* Create [Certification] from two [CertSynopsis] nodes.
|
||||
*/
|
||||
fun Certification(issuer: CertSynopsis, target: CertSynopsis): Certification =
|
||||
Certification(issuer, target, null, Date())
|
||||
|
||||
/**
|
||||
* Create [Certification] from two [CertSynopsis] nodes and a target [userId].
|
||||
*/
|
||||
fun Certification(issuer: CertSynopsis, target: CertSynopsis, userId: String): Certification =
|
||||
Certification(issuer, target, userId, Date())
|
||||
|
||||
/**
|
||||
* Add a single [CertSynopsis] built from a [String] fingerprint to the builder.
|
||||
*/
|
||||
fun Network.Builder.addNode(fingerprint: String): Network.Builder {
|
||||
return addNode(CertSynopsis(fingerprint))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single [CertSynopsis] built from a [String] fingerprint and [userId] to the builder.
|
||||
*/
|
||||
fun Network.Builder.addNode(fingerprint: String, userId: String): Network.Builder {
|
||||
return addNode(CertSynopsis(fingerprint, userId))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple [CertSynopsis] nodes built from [String] fingerprints to the builder.
|
||||
*/
|
||||
fun Network.Builder.addNodes(vararg fingerprints: String) {
|
||||
for (fingerprint in fingerprints) {
|
||||
addNode(fingerprint)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an edge between the [CertSynopsis] with fingerprint [issuer] and
|
||||
* the [CertSynopsis] with fingerprint [target].
|
||||
* If either the issuer or target node doesn't exist, throw an [IllegalArgumentException].
|
||||
*/
|
||||
fun Network.Builder.addEdge(issuer: String, target: String): Network.Builder {
|
||||
val issuerNode = nodes[Fingerprint(issuer)]!!
|
||||
val targetNode = nodes[Fingerprint(target)]!!
|
||||
return addEdge(Certification(issuerNode, targetNode))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an edge for [userId] between the [CertSynopsis] with fingerprint [issuer] and
|
||||
* the [CertSynopsis] with fingerprint [target].
|
||||
* If either the issuer or target node doesn't exist, throw an [IllegalArgumentException].
|
||||
*/
|
||||
fun Network.Builder.addEdge(issuer: String, target: String, userId: String): Network.Builder {
|
||||
val issuerNode = nodes[Fingerprint(issuer)]!!
|
||||
val targetNode = nodes[Fingerprint(target)]!!
|
||||
return addEdge(Certification(issuerNode, targetNode, userId))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an edge between the issuer and target node. If either of them doesn't exist, add
|
||||
* a new node for them to the builder.
|
||||
*/
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target) }
|
||||
return addEdge(Certification(issuerNode, targetNode))
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an edge for [userId] between the issuer and the target node. If either of them doesn't
|
||||
* exist, add a new node.
|
||||
* If the target node exists, but doesn't carry the [userId], replace it with a copy with
|
||||
* the [userId] inserted.
|
||||
*/
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String, userId: String): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer)}
|
||||
val targetNode = CertSynopsis(nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target, userId) }, userId)
|
||||
return addEdge(Certification(issuerNode, targetNode, userId))
|
||||
}
|
||||
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String, amount: Int, depth: Int): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target) }
|
||||
return addEdge(Certification(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), RegexSet.wildcard()))
|
||||
}
|
||||
|
||||
fun Network.Builder.buildEdge(issuer: String, target: String, amount: Int, depth: Int, regexSet: RegexSet): Network.Builder {
|
||||
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { CertSynopsis(issuer) }
|
||||
val targetNode = nodes.getOrPut(Fingerprint(target)) { CertSynopsis(target) }
|
||||
return addEdge(Certification(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), regexSet))
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reference time of the builder to now.
|
||||
*/
|
||||
fun Network.Builder.now(): Network.Builder {
|
||||
return setReferenceTime(ReferenceTime.now())
|
||||
}
|
||||
|
||||
fun Network.getEdgesFor(issuer: Fingerprint, target: Fingerprint): CertificationSet? {
|
||||
return edges[issuer]?.find { it.target.fingerprint == target }
|
||||
}
|
||||
|
||||
fun Network.getEdgesFor(issuer: String, target: String): CertificationSet? {
|
||||
return getEdgesFor(Fingerprint(issuer), Fingerprint(target))
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint): List<Certification>? {
|
||||
return getEdgeFor(issuer, target, null)
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint, userId: String?): List<Certification>? {
|
||||
return getEdgesFor(issuer, target)?.certifications?.get(userId)
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: String, target: String): List<Certification>? {
|
||||
return getEdgeFor(issuer, target, null)
|
||||
}
|
||||
|
||||
fun Network.getEdgeFor(issuer: String, target: String, userId: String?): List<Certification>? {
|
||||
return getEdgeFor(Fingerprint(issuer), Fingerprint(target), userId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Lambda with Receiver.
|
||||
*
|
||||
* @see <a href="https://betterprogramming.pub/test-data-creation-using-the-power-of-kotlin-dsl-9526a1fad05b"/>
|
||||
*/
|
||||
fun buildNetwork(builderAction: Network.Builder.() -> Unit): Network {
|
||||
val builder = Network.builder()
|
||||
builder.builderAction()
|
||||
return builder.build()
|
||||
}
|
||||
}
|
|
@ -5,15 +5,14 @@
|
|||
package org.pgpainless.wot.dijkstra
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.wot.dijkstra.sq.CertSynopsis
|
||||
import org.pgpainless.wot.dijkstra.sq.Certification
|
||||
import org.pgpainless.wot.dijkstra.sq.Network
|
||||
import org.pgpainless.wot.dijkstra.sq.Fingerprint
|
||||
import org.pgpainless.wot.dijkstra.sq.Network.Companion.empty
|
||||
import org.pgpainless.wot.dijkstra.sq.ReferenceTime.Companion.now
|
||||
import java.util.Date
|
||||
import org.pgpainless.wot.dijkstra.sq.RegexSet
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class NetworkTest {
|
||||
class NetworkTest: NetworkDSL {
|
||||
|
||||
@Test
|
||||
fun testEmptyNetworkIsEmpty() {
|
||||
|
@ -27,19 +26,66 @@ class NetworkTest {
|
|||
assertEquals(0, network.numberOfSignatures)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that setting referenceTime works`() {
|
||||
val ref = now()
|
||||
val network = buildNetwork {
|
||||
setReferenceTime(ref)
|
||||
}
|
||||
|
||||
assertEquals(ref, network.referenceTime)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that adding a single node works`() {
|
||||
val network = buildNetwork { addNode("A") }
|
||||
|
||||
assertEquals(1, network.nodes.size)
|
||||
assertTrue { network.nodes.containsKey(Fingerprint("A")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify that adding multiple, non-connected nodes works`() {
|
||||
val network = buildNetwork { addNodes("A", "B", "C", "D") }
|
||||
assertEquals(4, network.nodes.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSimpleNetwork() {
|
||||
val alice = CertSynopsis("A")
|
||||
val bob = CertSynopsis("B")
|
||||
val network = buildNetwork {
|
||||
buildEdge("A", "B")
|
||||
buildEdge("A", "C", "Charlie <charlie@example.org>")
|
||||
}
|
||||
|
||||
val edge = Certification(alice, bob, null, Date())
|
||||
assertEquals("Network with 3 nodes, 2 edges:\n" +
|
||||
"A certifies binding: null <-> B [120]\n" +
|
||||
"A certifies binding: Charlie <charlie@example.org> <-> C [120]\n",
|
||||
network.toString())
|
||||
}
|
||||
|
||||
val network = Network.builder()
|
||||
.addNode(alice)
|
||||
.addNode(bob)
|
||||
.addEdge(edge)
|
||||
.build()
|
||||
@Test
|
||||
fun `verify that network with 2 edges between 2 nodes keeps edges`() {
|
||||
val network = buildNetwork {
|
||||
buildEdge("A", "B")
|
||||
buildEdge("A", "B", "Bob")
|
||||
}
|
||||
|
||||
println(network)
|
||||
assertEquals(2, network.numberOfSignatures)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `play with depths, amounts and regexes`() {
|
||||
val network = buildNetwork {
|
||||
buildEdge("A", "B", 120, 10)
|
||||
buildEdge("B", "C", 60, 5, RegexSet.fromExpression("*"))
|
||||
buildEdge("A", "C", 10, 0)
|
||||
}
|
||||
|
||||
assertEquals(3, network.nodes.size)
|
||||
assertEquals(3, network.numberOfEdges)
|
||||
assertEquals(3, network.numberOfSignatures)
|
||||
|
||||
assertEquals(120, network.getEdgeFor("A", "B")!!.first().trustAmount)
|
||||
assertEquals(10, network.getEdgeFor("A", "B")!!.first().trustDepth.value())
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue