mutable-store
Version:
a mutable state management library for javascript
116 lines (98 loc) • 3.02 kB
text/typescript
import createMutableStore, { getProps } from './index'; // Adjust path as needed
describe('getProps', () => {
class Base {
baseMethod() {}
}
class Child extends Base {
childMethod() {}
}
it('should return own and inherited properties excluding built-ins', () => {
const instance = new Child();
const props = getProps(instance);
expect(props).toContain('childMethod');
expect(props).toContain('baseMethod');
expect(props).not.toContain('constructor');
});
it('should not include Object prototype props', () => {
const obj = {};
const props = getProps(obj);
expect(props).not.toContain('toString');
});
});
describe('createMutableStore', () => {
it('should throw if input is not an object', () => {
expect(() => createMutableStore(null as any)).toThrow('mutableState must be an object');
expect(() => createMutableStore(123 as any)).toThrow('mutableState must be an object');
});
it('should mark functions starting with set_ to trigger subscriptions', done => {
const store = createMutableStore({
value: 1,
set_value() {
this.value++;
}
});
store.subscribe(() => {
expect(store.value).toBe(2);
done();
});
store.set_value();
});
it('should make methods readonly', () => {
const store = createMutableStore({
fn() {}
});
expect(() => {
// @ts-ignore - We need to test the readonly behavior
store.fn = () => {};
}).toThrow();
});
it('should prevent extensions', () => {
const store = createMutableStore({ value: 123 });
expect(Object.isExtensible(store)).toBe(false);
});
it('should reject property named "subscribe"', () => {
expect(() =>
createMutableStore({ subscribe: () => {} })
).toThrow('subscribe is a reserved keyword');
});
it('should support subscription and unsubscription', () => {
const store = createMutableStore({ count: 0,set_count() {
this.count++;
} });
const fn = jest.fn();
const unsub = store.subscribe(fn);
store.set_count();
setTimeout(() => {
expect(fn).toHaveBeenCalled();
unsub();
store.set_count();
setTimeout(() => {
expect(fn).toHaveBeenCalledTimes(1); // Not called again
}, 0);
}, 0);
});
it('should auto-subscribe to nested stores', done => {
const inner = createMutableStore({
num: 0,
set_num() {
this.num++;
}
});
const outer = createMutableStore({
inner,
log() {}
});
outer.subscribe(() => {
expect(inner.num).toBe(1);
done();
});
inner.set_num();
});
it('should expose metadata flags', () => {
const store = createMutableStore({ a: 1 });
// @ts-ignore - We need to access internal metadata properties for testing
expect(store.___thisIsAMutableStore___).toBe(true);
// @ts-ignore - We need to access internal metadata properties for testing
expect(store.___version___).toBe(1);
});
});