Skip to content

Commit

Permalink
bring back other algorithm tests from odb
Browse files Browse the repository at this point in the history
  • Loading branch information
mpollmeier committed May 22, 2024
1 parent c5c7da0 commit b968cbc
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package flatgraph.algorithm

import org.scalatest.matchers.should.Matchers._
import org.scalatest.wordspec.AnyWordSpec

class DependencySequencerTests extends AnyWordSpec {

"empty graph" in {
DependencySequencer(Set.empty[Node]) shouldBe Seq.empty
}

"one node" in {
val A = new Node("A")
DependencySequencer(Set(A)) shouldBe Seq(Set(A))
}

"two independent nodes" in {
val A = new Node("A")
val B = new Node("B")
DependencySequencer(Set(A, B)) shouldBe Seq(Set(A, B))
}

"two nodes in sequence" in {
val A = new Node("A")
val B = new Node("B", Set(A))
DependencySequencer(Set(A, B)) shouldBe Seq(Set(A), Set(B))
}

"sequence and parallelism - simple 1" in {
val A = new Node("A")
val B = new Node("B")
val C = new Node("C", Set(A, B))
DependencySequencer(Set(A, B, C)) shouldBe Seq(Set(A, B), Set(C))
}

"sequence and parallelism - simple 2" in {
val A = new Node("A")
val B = new Node("B", Set(A))
val C = new Node("C", Set(A))
DependencySequencer(Set(A, B, C)) shouldBe Seq(Set(A), Set(B, C))
}

"throw error if it's not a DAG" in {
val A = new Node("A")
val B = new Node("B", Set(A))
A.parents = Set(B) // cycle in dependencies, not a DAG any longer
assertThrows[AssertionError](DependencySequencer(Set(A, B)))
}

"larger graph 1" in {
// format: off
/** \+-------------------+
* \| v
* \+---+ +---+ +---+ +---+
* \| A | --> | B | --> | C | --> | E |
* \+---+ +---+ +---+ +---+
* \| ^ v |
* \+---+ |
* \| D | ----------------+
* \+---+
*/
// format: on
val A = new Node("A")
val B = new Node("B", Set(A))
val C = new Node("C", Set(B))
val D = new Node("D", Set(B))
val E = new Node("E", Set(B, C, D))
DependencySequencer(Set(A, B, C, D, E)) shouldBe Seq(Set(A), Set(B), Set(C, D), Set(E))
}

"larger graph 2" in {
// format: off
/** \+-----------------------------+
* \| v
* \+---+ +---+ +---+ +---+ +---+
* \| A | --> | B | --> | D | --> | E | --> | F |
* \+---+ +---+ +---+ +---+ +---+
* \| ^ v |
* \+---+ |
* \| C | --------------------------+
* \+---+
*/
// format: on
val A = new Node("A")
val B = new Node("B", Set(A))
val C = new Node("C", Set(B))
val D = new Node("D", Set(B))
val E = new Node("E", Set(D))
val F = new Node("F", Set(B, C, E))
DependencySequencer(Set(A, B, C, D, E, F)) shouldBe Seq(Set(A), Set(B), Set(C, D), Set(E), Set(F))
// note: for task processing this isn't actually the optimal solution,
// because E will only start after [C|D] are finished... it wouldn't need to wait for C though...
}

class Node(val name: String, var parents: Set[Node] = Set.empty) {
override def toString = name
}
implicit def getParents: GetParents[Node] = (node: Node) => node.parents
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package flatgraph.algorithm

import org.scalatest.matchers.should.Matchers._
import org.scalatest.wordspec.AnyWordSpec

class LowestCommonAncestorsTests extends AnyWordSpec {

/** +--------------+
* | |
* | +---+ +---+ +---+ +---+ +---+ +---+
* | | A | --> | C | --> | D | --> | | --> | H | --> | I |
* | +---+ +---+ +---+ | | +---+ +---+
* | | | | |
* | | +---------------> | G |
* | v | |
* | +---+ | | +---+
* | | B | ----------------------> | | --> | F |
* | +---+ +---+ +---+
* | |
* | |
* | v
* | +---+
* +> | E |
* +---+
*
* created by `graph-easy --input=lca.eg`, where lca.eg:
* [A] --> [B],[C]
* [B] --> [E],[G]
* [C] --> [D],[E],[G]
* [D] --> [G]
* [G] --> [F],[H]
* [H] --> [I]
*/

val A = new Node("A", Set.empty)
val B = new Node("B", Set(A))
val C = new Node("C", Set(A))
val D = new Node("D", Set(C))
val E = new Node("E", Set(B, C))
val G = new Node("G", Set(B, C, D))
val F = new Node("F", Set(G))
val H = new Node("H", Set(G))
val I = new Node("I", Set(H))

"empty set" in {
val relevantNodes = Set.empty[Node]
LowestCommonAncestors(relevantNodes)(_.parents) shouldBe Set.empty
}

"one node" in {
val relevantNodes = Set(D)
LowestCommonAncestors(relevantNodes)(_.parents) shouldBe relevantNodes
}

"node E and H" in {
val relevantNodes = Set(E, H)
LowestCommonAncestors(relevantNodes)(_.parents) shouldBe Set(B, C)
}

"node B,E,H" in {
val relevantNodes = Set(B, E, H)
LowestCommonAncestors(relevantNodes)(_.parents) shouldBe Set(A)
}

"node A,B,E,H" in {
val relevantNodes = Set(A, B, E, H)
LowestCommonAncestors(relevantNodes)(_.parents) shouldBe Set.empty
}

"cyclic dependencies" in {
val A = new Node("A", Set.empty)
val B = new Node("B", Set(A))
A.parents = Set(B) // cycle in dependencies, not a DAG any longer
LowestCommonAncestors(Set(A, B)) shouldBe Set.empty
}

class Node(val name: String, var parents: Set[Node]) {
override def toString = name
}
implicit def getParents: GetParents[Node] = (node: Node) => node.parents
}

0 comments on commit b968cbc

Please sign in to comment.