Skip to content

Commit

Permalink
feat(TestRun): get previous/next sibling node
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche committed Dec 12, 2024
1 parent 2da153b commit 6eded6d
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/conductor/TestRun/TestFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class TestFunctionStack extends TestElementStack<TestFunction> {
return func
}

declare children: undefined
declare children: never

protected static init(instance: TestFunctionStack) {
TestElementStack.init(instance)
Expand Down
5 changes: 3 additions & 2 deletions src/conductor/TestRun/TestGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { TestErrorList } from './TestError'
import { TestElementInstance, TestElementStack } from './TestElement'
import { TestInstanceIndex, TestStackIndex } from './TestIndex'
import { TestSuite, TestSuiteStack } from './TestSuite'
import { TestNodeChildren } from './TestNode'

export class TestGroupStack extends TestElementStack<TestGroup> {
static create(
Expand All @@ -14,7 +15,7 @@ export class TestGroupStack extends TestElementStack<TestGroup> {
return group
}

readonly children = new Map<string, TestElementStack>()
readonly children = new TestNodeChildren<TestElementStack>()
readonly index = new TestStackIndex()
}

Expand All @@ -34,7 +35,7 @@ export class TestGroup extends TestElementInstance {
}

declare readonly stack: TestGroupStack
readonly children = new Map<string, TestElementInstance>()
readonly children = new TestNodeChildren<TestElementInstance>()
readonly index = new TestInstanceIndex()

readonly errors = new TestErrorList(error => {
Expand Down
86 changes: 82 additions & 4 deletions src/conductor/TestRun/TestNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TestRunInstance } from './TestRun'

export abstract class TestNodeStack<T extends TestNodeInstance = TestNodeInstance> extends EventEmitter<TestEventMap> {
readonly instances = new Map<TestRunInstance, T>()
readonly children?: Map<string, TestNodeStack>
readonly children?: TestNodeChildren<TestNodeStack>
readonly index?: TestStackIndex

protected constructor(
Expand All @@ -15,19 +15,26 @@ export abstract class TestNodeStack<T extends TestNodeInstance = TestNodeInstanc
super(parent)
}
protected static init(instance: TestNodeStack): void {
instance.parent?.children?.set(instance.ident, instance)
instance.parent?.children?.add(instance.ident, instance)
}

*ancestors(includeSelf = true) {
for(let el = includeSelf ? this : this.parent; el; el = el.parent) {
yield el
}
}

get previousSibling() {
return this.parent?.children?.previous(this)
}
get nextSibling() {
return this.parent?.children?.next(this)
}
}

export abstract class TestNodeInstance extends EventEmitter<TestEventMap>{
abstract readonly run: TestRunInstance
readonly children?: Map<string, TestNodeInstance>
readonly children?: TestNodeChildren<TestNodeInstance>
readonly index?: TestInstanceIndex

protected constructor(
Expand All @@ -39,7 +46,7 @@ export abstract class TestNodeInstance extends EventEmitter<TestEventMap>{
}
protected static init(instance: TestNodeInstance): void {
instance.stack.instances.set(instance.run, instance)
instance.parent?.children?.set(instance.ident, instance)
instance.parent?.children?.add(instance.ident, instance)
}

protected dispatch<K extends keyof TestEventMap>(type: K, init: TestEventMap[K]): void {
Expand All @@ -52,4 +59,75 @@ export abstract class TestNodeInstance extends EventEmitter<TestEventMap>{
yield el
}
}

get previousSibling() {
return this.parent?.children?.previous(this)
}
get nextSibling() {
return this.parent?.children?.next(this)
}
}

export class TestNodeChildren<T, Ident = string> implements Iterable<[T, Ident, number], void, undefined> {
#ids = new Map<T, number>()
#idents = new Map<Ident, T>()
#items: T[] = []

add(ident: Ident, item: T) {
if (this.#idents.has(ident)) {
throw new Error(`Child "${String(ident)}" already exists.`)
}

const i = this.#items.length
this.#items.push(item)
this.#ids.set(item, i)
this.#idents.set(ident, item)
}

has(ident: Ident) {
return this.#idents.has(ident)
}

get(ident: Ident) {
return this.#idents.get(ident)
}

get size() {
return this.#idents.size
}

getPos(item: T) {
const i = this.#ids.get(item)
if (i === undefined) {
throw new Error('Item is not a child')
}
return i
}

nth(i: number): T|undefined {
return this.#items[i]
}

previous(item: T) {
return this.nth(this.getPos(item) - 1)
}

next(item: T) {
return this.nth(this.getPos(item) + 1)
}

*[Symbol.iterator](): Generator<[T, Ident, number], void, undefined> {
let i = 0
for (const [ident, item] of this.#idents) {
yield [item, ident, i]
}
}

values() {
return this.#items.values()
}

keys() {
return this.#idents.keys()
}
}
6 changes: 3 additions & 3 deletions src/conductor/TestRun/TestRun.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TestConductor } from '../TestConductor'
import { TestRunInstanceIndex, TestRunStackIndex } from './TestIndex'
import { TestNodeInstance, TestNodeStack } from './TestNode'
import { TestNodeChildren, TestNodeInstance, TestNodeStack } from './TestNode'
import { TestSuite, TestSuiteStack } from './TestSuite'

export type TestFile = {
Expand All @@ -25,7 +25,7 @@ export class TestRunStack extends TestNodeStack<TestRunInstance> {

readonly runs = new Map<TestConductor, TestRunInstance>()
readonly instances = new Map<TestRunInstance, TestRunInstance>()
readonly children = new Map<string, TestSuiteStack>()
readonly children = new TestNodeChildren<TestSuiteStack>()
readonly index = new TestRunStackIndex()
readonly suites = this.children

Expand All @@ -52,7 +52,7 @@ export class TestRunInstance extends TestNodeInstance {
}

readonly run: TestRunInstance = this
readonly children = new Map<string, TestSuite>()
readonly children = new TestNodeChildren<TestSuite>()
readonly index = new TestRunInstanceIndex()
readonly suites = this.children

Expand Down
11 changes: 3 additions & 8 deletions src/conductor/TestRun/TestSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TestCompleteData, TestErrorData, TestReporter, TestResultData, TestSche
import { TestError, TestErrorList } from './TestError'
import { TestFunction } from './TestFunction'
import { TestGroup } from './TestGroup'
import { TestNodeInstance, TestNodeStack } from './TestNode'
import { TestNodeChildren, TestNodeInstance, TestNodeStack } from './TestNode'
import { TestElementInstance, TestElementStack } from './TestElement'
import { TestResult } from './TestResult'
import { TestRunInstance, TestRunStack } from './TestRun'
Expand All @@ -23,7 +23,7 @@ export class TestSuiteStack extends TestNodeStack<TestSuite> {
return suite
}

readonly children = new Map<string, TestElementStack>()
readonly children = new TestNodeChildren<TestElementStack>()
readonly index = new TestStackIndex()

protected constructor(
Expand All @@ -37,10 +37,6 @@ export class TestSuiteStack extends TestNodeStack<TestSuite> {

super(parent, url)
}
protected static init(instance: TestSuiteStack): void {
TestNodeStack.init(instance)
instance.parent.suites.set(instance.ident, instance)
}
}

export class TestSuite extends TestNodeInstance {
Expand All @@ -56,7 +52,7 @@ export class TestSuite extends TestNodeInstance {
}

declare readonly stack: TestSuiteStack
readonly children = new Map<string, TestNodeInstance>()
readonly children = new TestNodeChildren<TestNodeInstance>()
readonly index = new TestInstanceIndex()
readonly suite: TestSuite = this

Expand All @@ -76,7 +72,6 @@ export class TestSuite extends TestNodeInstance {
}
protected static init(instance: TestSuite): void {
TestNodeInstance.init(instance)
instance.run.suites.set(instance.url, instance)
instance.run.index.suites[instance.state].add(instance)
instance.run.stack.index.suites[instance.state].add(instance)
}
Expand Down

0 comments on commit 6eded6d

Please sign in to comment.