Skip to content

Commit

Permalink
Adding tests and fixing issue with notification phase error
Browse files Browse the repository at this point in the history
  • Loading branch information
divdavem committed Nov 5, 2024
1 parent 9642174 commit dbc8b77
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 1 deletion.
100 changes: 100 additions & 0 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,93 @@ describe('stores', () => {
expect(store2()).toBe(1);
});

it('should throw when trying to read a signal during the notification phase', () => {
const store = writable(0);
let success = 0;
const errors: any[] = [];
const unsubscribe = store.subscribe({
pause() {
try {
store.get();
success++;
} catch (error) {
errors.push(error);
}
},
});
store.set(1);
expect(success).toBe(0);
expect(errors.length).toBe(1);
expect(errors[0].message).toContain('during the notification phase');
unsubscribe();
});

it('should throw when trying to read an up-to-date computed signal during the notification phase', () => {
const w1 = writable(0);
const s1 = computed(() => w1());
s1();
const store = writable(0);
let success = 0;
const errors: any[] = [];
const unsubscribe = store.subscribe({
pause() {
try {
s1.get();
success++;
} catch (error) {
errors.push(error);
}
},
});
store.set(1);
expect(success).toBe(0);
expect(errors.length).toBe(1);
expect(errors[0].message).toContain('during the notification phase');
unsubscribe();
});

it('should throw when trying to subscribe to a signal during the notification phase', () => {
const store = writable(0);
let success = 0;
const errors: any[] = [];
const unsubscribe = store.subscribe({
pause() {
try {
store.subscribe(() => {});
success++;
} catch (error) {
errors.push(error);
}
},
});
store.set(1);
expect(success).toBe(0);
expect(errors.length).toBe(1);
expect(errors[0].message).toContain('during the notification phase');
unsubscribe();
});

it('should throw when trying to write a signal during notification phase', () => {
const store = writable(0);
let success = 0;
const errors: any[] = [];
const unsubscribe = store.subscribe({
pause() {
try {
store.set(2);
success++;
} catch (error) {
errors.push(error);
}
},
});
store.set(1);
expect(success).toBe(0);
expect(errors.length).toBe(1);
expect(errors[0].message).toContain('during the notification phase');
unsubscribe();
});

it('should work to use subscribe only and use it in a computed', () => {
const store1 = writable(0);
const store2 = asReadable({ subscribe: store1.subscribe });
Expand Down Expand Up @@ -2797,6 +2884,19 @@ describe('stores', () => {
});

describe('computed', () => {
it('should work with a basic store class', () => {
class CounterStore extends Store<number> {
increase() {
this.update((value) => value + 1);
}
}
const store = new CounterStore(0);
const doubleStore = computed(() => store.get() * 2);
expect(doubleStore()).toBe(0);
store.increase();
expect(doubleStore()).toBe(2);
});

it('should not call equal with undefined during the first computation', () => {
const a = writable(1);
const equal = vi.fn(Object.is);
Expand Down
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ class RawStore<T> implements SignalStore<T>, SubscribableStore<T> {

markConsumersDirty() {
const prevNotificationPhase = notificationPhase;
notificationPhase = true;
try {
const consumerLinks = this.consumerLinks;
if (consumerLinks) {
Expand Down Expand Up @@ -400,7 +401,7 @@ class RawComputed<T> extends RawComputedOrDerived<T> implements Consumer, Active
}

override get(): T {
if (!activeConsumer && this.epoch === epoch && !this.hasVisibleOnUse) {
if (!activeConsumer && !notificationPhase && this.epoch === epoch && !this.hasVisibleOnUse) {
return this.readValue();
}
return super.get();
Expand Down

0 comments on commit dbc8b77

Please sign in to comment.