-
Notifications
You must be signed in to change notification settings - Fork 39
Description
This might be out-of-scope for this package, but I find myself wanting some debugging tooling to inspect what character(s) I am missing in my marble diagrams. The provided snippet is basically the reverse of the notification mappings and it seems to generate the marble diagrams I am expecting. There are still scenarios I am not accounting for such as emissions within the same frame and using parenthesis, but this is massively helpful when trying to reason about more complex observables that may have multiple pipe operators. I can't find any existing utility packages that already do this.
import { getTestScheduler } from 'jasmine-marbles';
import { Observable } from 'rxjs';
export function createMarbleDiagram<T>(
source: Observable<T>,
values: Record<string, T>
): Array<string> {
const scheduler = getTestScheduler();
let diagram: Array<string> = [];
let lastFrame = scheduler.frame;
source.subscribe({
next: (value: T) => {
appendFrames(scheduler.frame-lastFrame, diagram);
lastFrame = scheduler.frame;
diagram.push(
Object.keys(values).find((key) => values[key] === value) || '?'
);
},
error: (error) => {
appendFrames(scheduler.frame-lastFrame, diagram);
lastFrame = scheduler.frame;
diagram.push('#');
},
complete: () => {
appendFrames(scheduler.frame-lastFrame, diagram);
lastFrame = scheduler.frame;
diagram.push('|');
},
});
return diagram;
}
function appendFrames(frameDuration: number, diagram: Array<string>) {
const lastEmissionDeduction = diagram.length ? 10 : 0;
const frames = Math.floor((frameDuration - lastEmissionDeduction)/10);
for(let i = 0; i < frames; i++) {
diagram.push('-');
}
}
Here is a really simple test from my angular project using this method to debug
it('should combine data from DataService and an additional source in the correct order', () => {
const values = { a: { name: 'Test Data 1' }, b: { name: 'Test Data 2' } };
let source1 = cold('-a---|', values);
let source2 = cold('---b-|', values);
someHttpService.getData.and.returnValue(source1);
someHttpService.getMoreData.and.returnValue(source2);
const expectedObservable = cold('-a-b-|', values);
const result = component.getSequentialDataFromHttp();
const diagram = createMarbleDiagram(result, values); // Debug
expect(result).toBeObservable(expectedObservable);
getTestScheduler().flush();
console.debug(`Expect marble: -a-b-|`); // Debug
console.debug(`Actual marble: ${diagram.join('')}`); // Debug
});
which results in the output
DEBUG: 'Expect marble: -a-b-|'
DEBUG: 'Actual marble: -a-b-|'