1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-12-24 11:57:59 +01:00

Diabetes levels of DSL and sugar

This commit is contained in:
Paul Schaub 2023-07-07 18:49:00 +02:00
parent fce8634e4e
commit dc5d6fca51
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
6 changed files with 254 additions and 22 deletions

View file

@ -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"

View file

@ -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())

View file

@ -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()

View file

@ -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())
}
}

View file

@ -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()
}
}

View file

@ -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())
}
}