tests
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import { appendToFrozenArray, UniqueBehaviorSubject } from "./unique-behavior-subject";
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UniqueObjectBehaviorSubject
|
||||
* @extends {UniqueBehaviorSubject<T>}
|
||||
* @description - A RxJS UniqueObjectBehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
||||
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||
*
|
||||
* The UniqueObjectBehaviorSubject provides methods to append data when the data is an Object.
|
||||
*/
|
||||
|
||||
export class UniqueArrayBehaviorSubject<T> extends UniqueBehaviorSubject<T[]> {
|
||||
|
||||
|
||||
constructor(initialData: T[], private _uniqueCompare?: (existingEntry: T, newEntry: T) => boolean) {
|
||||
super(initialData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @method append
|
||||
* @param {Partial<T>} partialData - A object containing some of the data for this Subject.
|
||||
* @description - Append some new data to this Object.
|
||||
* @example <caption>Example append some data.</caption>
|
||||
* const data = [
|
||||
* { key: 1, value: 'foo'},
|
||||
* { key: 2, value: 'bar'}
|
||||
* ];
|
||||
* const mySubject = new UniqueArrayBehaviorSubject(data);
|
||||
* mySubject.append({ key: 1, value: 'replaced-foo'});
|
||||
*/
|
||||
appendOne(entry: T) {
|
||||
this.next(appendToFrozenArray(this.getValue(), entry, this._uniqueCompare))
|
||||
}
|
||||
|
||||
/**
|
||||
* @method append
|
||||
* @param {T[]} entries - A array of new data to be added in this Subject.
|
||||
* @description - Append some new data to this Object, if it compares to existing data it will replace it.
|
||||
* @example <caption>Example append some data.</caption>
|
||||
* const data = [
|
||||
* { key: 1, value: 'foo'},
|
||||
* { key: 2, value: 'bar'}
|
||||
* ];
|
||||
* const mySubject = new UniqueArrayBehaviorSubject(data);
|
||||
* mySubject.append([
|
||||
* { key: 1, value: 'replaced-foo'},
|
||||
* { key: 3, value: 'another-bla'}
|
||||
* ]);
|
||||
*/
|
||||
append(entries: T[]) {
|
||||
entries.forEach(x => this.appendOne(x))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { expect } from '@open-wc/testing';
|
||||
import { createObservablePart, UniqueBehaviorSubject } from './unique-behavior-subject';
|
||||
|
||||
describe('UniqueBehaviorSubject', () => {
|
||||
|
||||
type ObjectType = {key: string, another: string};
|
||||
|
||||
let subject: UniqueBehaviorSubject<ObjectType>;
|
||||
let initialData: ObjectType;
|
||||
|
||||
beforeEach(() => {
|
||||
initialData = {key: 'some', another: 'myValue'};
|
||||
subject = new UniqueBehaviorSubject(initialData);
|
||||
});
|
||||
|
||||
|
||||
it('getValue gives the initial data', () => {
|
||||
expect(subject.value.another).to.be.equal(initialData.another);
|
||||
});
|
||||
|
||||
it('update via next', () => {
|
||||
subject.next({key: 'some', another: 'myNewValue'});
|
||||
expect(subject.value.another).to.be.equal('myNewValue');
|
||||
});
|
||||
|
||||
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
||||
|
||||
const observer = subject.asObservable();
|
||||
observer.subscribe((value) => {
|
||||
expect(value).to.be.equal(initialData);
|
||||
});
|
||||
observer.subscribe((value) => {
|
||||
expect(value).to.be.equal(initialData);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('use createObservablePart, updates on its specific change.', (done) => {
|
||||
|
||||
let amountOfCallbacks = 0;
|
||||
|
||||
const subObserver = createObservablePart(subject, data => data.another);
|
||||
subObserver.subscribe((value) => {
|
||||
amountOfCallbacks++;
|
||||
if(amountOfCallbacks === 1) {
|
||||
expect(value).to.be.equal('myValue');
|
||||
}
|
||||
if(amountOfCallbacks === 2) {
|
||||
expect(value).to.be.equal('myNewValue');
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
subject.next({key: 'change_this_first_should_not_trigger_update', another: 'myValue'});
|
||||
subject.next({key: 'some', another: 'myNewValue'});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -40,10 +40,10 @@ export function naiveObjectComparison(objOne: any, objTwo: any): boolean {
|
||||
* const newDataSet = appendToFrozenArray(mySubject.getValue(), entry, x => x.key === key);
|
||||
* mySubject.next(newDataSet);
|
||||
*/
|
||||
export function appendToFrozenArray<T>(data: T[], entry: T, uniqueMethod?: (entry: T) => boolean): T[] {
|
||||
export function appendToFrozenArray<T>(data: T[], entry: T, uniqueMethod?: (existingEntry: T, newEntry: T) => boolean): T[] {
|
||||
const unFrozenDataSet = [...data];
|
||||
if(uniqueMethod) {
|
||||
const indexToReplace = unFrozenDataSet.findIndex(uniqueMethod);
|
||||
const indexToReplace = unFrozenDataSet.findIndex((x) => uniqueMethod(x, entry));
|
||||
if(indexToReplace !== -1) {
|
||||
unFrozenDataSet[indexToReplace] = entry;
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { expect } from '@open-wc/testing';
|
||||
import { createObservablePart } from './unique-behavior-subject';
|
||||
import { UniqueObjectBehaviorSubject } from './unique-object-behavior-subject';
|
||||
|
||||
describe('UniqueObjectBehaviorSubject', () => {
|
||||
|
||||
type ObjectType = {key: string, another: string};
|
||||
|
||||
let subject: UniqueObjectBehaviorSubject<ObjectType>;
|
||||
let initialData: ObjectType;
|
||||
|
||||
beforeEach(() => {
|
||||
initialData = {key: 'some', another: 'myValue'};
|
||||
subject = new UniqueObjectBehaviorSubject(initialData);
|
||||
});
|
||||
|
||||
|
||||
it('replays latests, no matter the amount of subscriptions.', (done) => {
|
||||
|
||||
const observer = subject.asObservable();
|
||||
observer.subscribe((value) => {
|
||||
expect(value).to.be.equal(initialData);
|
||||
});
|
||||
observer.subscribe((value) => {
|
||||
expect(value).to.be.equal(initialData);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('use createObservablePart, updates on its specific change.', (done) => {
|
||||
|
||||
let amountOfCallbacks = 0;
|
||||
|
||||
const subObserver = createObservablePart(subject, data => data.another);
|
||||
subObserver.subscribe((value) => {
|
||||
amountOfCallbacks++;
|
||||
if(amountOfCallbacks === 1) {
|
||||
expect(value).to.be.equal('myValue');
|
||||
}
|
||||
if(amountOfCallbacks === 2) {
|
||||
expect(value).to.be.equal('myNewValue');
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
subject.append({key: 'change_this_first_should_not_trigger_update'});
|
||||
subject.append({another: 'myNewValue'});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UniqueBehaviorSubject } from "./unique-behavior-subject";
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UniqueObjectBehaviorSubject
|
||||
* @extends {UniqueBehaviorSubject<T>}
|
||||
* @description - A RxJS UniqueObjectBehaviorSubject which deepFreezes the object-data to ensure its not manipulated from any implementations.
|
||||
* Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content.
|
||||
*
|
||||
* The UniqueObjectBehaviorSubject provides methods to append data when the data is an Object.
|
||||
*/
|
||||
export class UniqueObjectBehaviorSubject<T> extends UniqueBehaviorSubject<T> {
|
||||
|
||||
/**
|
||||
* @method append
|
||||
* @param {Partial<T>} partialData - A object containing some of the data for this Subject.
|
||||
* @description - Append some new data to this Object.
|
||||
* @example <caption>Example append some data.</caption>
|
||||
* const data = {key: 'myKey', value: 'myInitialValue'};
|
||||
* const mySubject = new UniqueObjectBehaviorSubject(data)
|
||||
* mySubject.append({value: 'myNewValue'})
|
||||
*/
|
||||
append(partialData: Partial<T>) {
|
||||
this.next({ ...this.getValue(), ...partialData });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user