
8 changed files with 681 additions and 47 deletions
-
12packages/observer/__tests__/autorun.spec.ts
-
3packages/observer/__tests__/collections.spec.ts
-
210packages/observer/__tests__/collections/Map.spec.ts
-
279packages/observer/__tests__/collections/Set.spec.ts
-
77packages/observer/__tests__/collections/WeakMap.spec.ts
-
79packages/observer/__tests__/collections/WeakSet.spec.ts
-
58packages/observer/src/collectionHandlers.ts
-
10packages/scheduler/__tests__/scheduler.spec.ts
@ -1,3 +0,0 @@ |
|||
describe('observer/collections', () => { |
|||
describe('Map', () => {}) |
|||
}) |
@ -0,0 +1,210 @@ |
|||
import { observable, autorun, unwrap, isObservable } from '../../src' |
|||
|
|||
describe('observer/collections', () => { |
|||
describe('Map', () => { |
|||
test('instanceof', () => { |
|||
const original = new Map() |
|||
const observed = observable(original) |
|||
expect(isObservable(observed)).toBe(true) |
|||
expect(original instanceof Map).toBe(true) |
|||
expect(observed instanceof Map).toBe(true) |
|||
}) |
|||
|
|||
it('should observe mutations', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => { |
|||
dummy = map.get('key') |
|||
}) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
map.set('key', 'value') |
|||
expect(dummy).toBe('value') |
|||
map.set('key', 'value2') |
|||
expect(dummy).toBe('value2') |
|||
map.delete('key') |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
|
|||
it('should observe size mutations', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => (dummy = map.size)) |
|||
|
|||
expect(dummy).toBe(0) |
|||
map.set('key1', 'value') |
|||
map.set('key2', 'value2') |
|||
expect(dummy).toBe(2) |
|||
map.delete('key1') |
|||
expect(dummy).toBe(1) |
|||
map.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe for of iteration', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
// eslint-disable-next-line no-unused-vars
|
|||
for (let [key, num] of map) { |
|||
key |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
map.set('key1', 3) |
|||
expect(dummy).toBe(3) |
|||
map.set('key2', 2) |
|||
expect(dummy).toBe(5) |
|||
map.delete('key1') |
|||
expect(dummy).toBe(2) |
|||
map.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe forEach iteration', () => { |
|||
let dummy: any |
|||
const map = observable(new Map()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
map.forEach((num: any) => (dummy += num)) |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
map.set('key1', 3) |
|||
expect(dummy).toBe(3) |
|||
map.set('key2', 2) |
|||
expect(dummy).toBe(5) |
|||
map.delete('key1') |
|||
expect(dummy).toBe(2) |
|||
map.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe keys iteration', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
for (let key of map.keys()) { |
|||
dummy += key |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
map.set(3, 3) |
|||
expect(dummy).toBe(3) |
|||
map.set(2, 2) |
|||
expect(dummy).toBe(5) |
|||
map.delete(3) |
|||
expect(dummy).toBe(2) |
|||
map.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe values iteration', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
for (let num of map.values()) { |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
map.set('key1', 3) |
|||
expect(dummy).toBe(3) |
|||
map.set('key2', 2) |
|||
expect(dummy).toBe(5) |
|||
map.delete('key1') |
|||
expect(dummy).toBe(2) |
|||
map.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe entries iteration', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
// eslint-disable-next-line no-unused-vars
|
|||
for (let [key, num] of map.entries()) { |
|||
key |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
map.set('key1', 3) |
|||
expect(dummy).toBe(3) |
|||
map.set('key2', 2) |
|||
expect(dummy).toBe(5) |
|||
map.delete('key1') |
|||
expect(dummy).toBe(2) |
|||
map.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should be triggered by clearing', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => (dummy = map.get('key'))) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
map.set('key', 3) |
|||
expect(dummy).toBe(3) |
|||
map.clear() |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
|
|||
it('should not observe custom property mutations', () => { |
|||
let dummy |
|||
const map: any = observable(new Map()) |
|||
autorun(() => (dummy = map.customProp)) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
map.customProp = 'Hello World' |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
|
|||
it('should not observe non value changing mutations', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
const mapSpy = jest.fn(() => (dummy = map.get('key'))) |
|||
autorun(mapSpy) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(1) |
|||
map.set('key', 'value') |
|||
expect(dummy).toBe('value') |
|||
expect(mapSpy).toHaveBeenCalledTimes(2) |
|||
map.set('key', 'value') |
|||
expect(dummy).toBe('value') |
|||
expect(mapSpy).toHaveBeenCalledTimes(2) |
|||
map.delete('key') |
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(3) |
|||
map.delete('key') |
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(3) |
|||
map.clear() |
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(3) |
|||
}) |
|||
|
|||
it('should not observe raw data', () => { |
|||
let dummy |
|||
const map = observable(new Map()) |
|||
autorun(() => (dummy = unwrap(map).get('key'))) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
map.set('key', 'Hello') |
|||
expect(dummy).toBe(undefined) |
|||
map.delete('key') |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
}) |
|||
}) |
@ -0,0 +1,279 @@ |
|||
import { observable, autorun, isObservable, unwrap } from '../../src' |
|||
|
|||
describe('Set', () => { |
|||
it('instanceof', () => { |
|||
const original = new Set() |
|||
const observed = observable(original) |
|||
expect(isObservable(observed)).toBe(true) |
|||
expect(original instanceof Set).toBe(true) |
|||
expect(observed instanceof Set).toBe(true) |
|||
}) |
|||
|
|||
it('should observe mutations', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => (dummy = set.has('value'))) |
|||
|
|||
expect(dummy).toBe(false) |
|||
set.add('value') |
|||
expect(dummy).toBe(true) |
|||
set.delete('value') |
|||
expect(dummy).toBe(false) |
|||
}) |
|||
|
|||
it('should observe for of iteration', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
for (let num of set) { |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add(2) |
|||
set.add(1) |
|||
expect(dummy).toBe(3) |
|||
set.delete(2) |
|||
expect(dummy).toBe(1) |
|||
set.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe forEach iteration', () => { |
|||
let dummy: any |
|||
const set = observable(new Set()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
set.forEach(num => (dummy += num)) |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add(2) |
|||
set.add(1) |
|||
expect(dummy).toBe(3) |
|||
set.delete(2) |
|||
expect(dummy).toBe(1) |
|||
set.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe values iteration', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
for (let num of set.values()) { |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add(2) |
|||
set.add(1) |
|||
expect(dummy).toBe(3) |
|||
set.delete(2) |
|||
expect(dummy).toBe(1) |
|||
set.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe keys iteration', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
for (let num of set.keys()) { |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add(2) |
|||
set.add(1) |
|||
expect(dummy).toBe(3) |
|||
set.delete(2) |
|||
expect(dummy).toBe(1) |
|||
set.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should observe entries iteration', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
// eslint-disable-next-line no-unused-vars
|
|||
for (let [key, num] of set.entries()) { |
|||
key |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add(2) |
|||
set.add(1) |
|||
expect(dummy).toBe(3) |
|||
set.delete(2) |
|||
expect(dummy).toBe(1) |
|||
set.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should be triggered by clearing', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => (dummy = set.has('key'))) |
|||
|
|||
expect(dummy).toBe(false) |
|||
set.add('key') |
|||
expect(dummy).toBe(true) |
|||
set.clear() |
|||
expect(dummy).toBe(false) |
|||
}) |
|||
|
|||
it('should not observe custom property mutations', () => { |
|||
let dummy |
|||
const set: any = observable(new Set()) |
|||
autorun(() => (dummy = set.customProp)) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
set.customProp = 'Hello World' |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
|
|||
it('should observe size mutations', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => (dummy = set.size)) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add('value') |
|||
set.add('value2') |
|||
expect(dummy).toBe(2) |
|||
set.delete('value') |
|||
expect(dummy).toBe(1) |
|||
set.clear() |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should not observe non value changing mutations', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
const setSpy = jest.fn(() => (dummy = set.has('value'))) |
|||
autorun(setSpy) |
|||
|
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(1) |
|||
set.add('value') |
|||
expect(dummy).toBe(true) |
|||
expect(setSpy).toHaveBeenCalledTimes(2) |
|||
set.add('value') |
|||
expect(dummy).toBe(true) |
|||
expect(setSpy).toHaveBeenCalledTimes(2) |
|||
set.delete('value') |
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(3) |
|||
set.delete('value') |
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(3) |
|||
set.clear() |
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(3) |
|||
}) |
|||
|
|||
it('should not observe raw data', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => (dummy = unwrap(set).has('value'))) |
|||
|
|||
expect(dummy).toBe(false) |
|||
set.add('value') |
|||
expect(dummy).toBe(false) |
|||
}) |
|||
|
|||
it('should not observe raw iterations', () => { |
|||
let dummy = 0 |
|||
const set = observable(new Set()) |
|||
autorun(() => { |
|||
dummy = 0 |
|||
for (let [num] of unwrap(set).entries()) { |
|||
dummy += num |
|||
} |
|||
for (let num of unwrap(set).keys()) { |
|||
dummy += num |
|||
} |
|||
for (let num of unwrap(set).values()) { |
|||
dummy += num |
|||
} |
|||
unwrap(set).forEach(num => { |
|||
dummy += num |
|||
}) |
|||
for (let num of unwrap(set)) { |
|||
dummy += num |
|||
} |
|||
}) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add(2) |
|||
set.add(3) |
|||
expect(dummy).toBe(0) |
|||
set.delete(2) |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should not be triggered by raw mutations', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => (dummy = set.has('value'))) |
|||
|
|||
expect(dummy).toBe(false) |
|||
unwrap(set).add('value') |
|||
expect(dummy).toBe(false) |
|||
dummy = true |
|||
unwrap(set).delete('value') |
|||
expect(dummy).toBe(true) |
|||
unwrap(set).clear() |
|||
expect(dummy).toBe(true) |
|||
}) |
|||
|
|||
it('should not observe raw size mutations', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => (dummy = unwrap(set).size)) |
|||
|
|||
expect(dummy).toBe(0) |
|||
set.add('value') |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should not be triggered by raw size mutations', () => { |
|||
let dummy |
|||
const set = observable(new Set()) |
|||
autorun(() => (dummy = set.size)) |
|||
|
|||
expect(dummy).toBe(0) |
|||
unwrap(set).add('value') |
|||
expect(dummy).toBe(0) |
|||
}) |
|||
|
|||
it('should support objects as key', () => { |
|||
let dummy |
|||
const key = {} |
|||
const set = observable(new Set()) |
|||
const setSpy = jest.fn(() => (dummy = set.has(key))) |
|||
autorun(setSpy) |
|||
|
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(1) |
|||
|
|||
set.add({}) |
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(1) |
|||
|
|||
set.add(key) |
|||
expect(dummy).toBe(true) |
|||
expect(setSpy).toHaveBeenCalledTimes(2) |
|||
}) |
|||
}) |
@ -0,0 +1,77 @@ |
|||
import { observable, autorun, unwrap, isObservable } from '../../src' |
|||
|
|||
describe('observer/collections/WeakMap', () => { |
|||
test('instanceof', () => { |
|||
const original = new WeakMap() |
|||
const observed = observable(original) |
|||
expect(isObservable(observed)).toBe(true) |
|||
expect(original instanceof WeakMap).toBe(true) |
|||
expect(observed instanceof WeakMap).toBe(true) |
|||
}) |
|||
|
|||
it('should observe mutations', () => { |
|||
let dummy |
|||
const key = {} |
|||
const map = observable(new WeakMap()) |
|||
autorun(() => { |
|||
dummy = map.get(key) |
|||
}) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
map.set(key, 'value') |
|||
expect(dummy).toBe('value') |
|||
map.set(key, 'value2') |
|||
expect(dummy).toBe('value2') |
|||
map.delete(key) |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
|
|||
it('should not observe custom property mutations', () => { |
|||
let dummy |
|||
const map: any = observable(new Map()) |
|||
autorun(() => (dummy = map.customProp)) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
map.customProp = 'Hello World' |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
|
|||
it('should not observe non value changing mutations', () => { |
|||
let dummy |
|||
const key = {} |
|||
const map = observable(new Map()) |
|||
const mapSpy = jest.fn(() => (dummy = map.get(key))) |
|||
autorun(mapSpy) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(1) |
|||
map.set(key, 'value') |
|||
expect(dummy).toBe('value') |
|||
expect(mapSpy).toHaveBeenCalledTimes(2) |
|||
map.set(key, 'value') |
|||
expect(dummy).toBe('value') |
|||
expect(mapSpy).toHaveBeenCalledTimes(2) |
|||
map.delete(key) |
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(3) |
|||
map.delete(key) |
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(3) |
|||
map.clear() |
|||
expect(dummy).toBe(undefined) |
|||
expect(mapSpy).toHaveBeenCalledTimes(3) |
|||
}) |
|||
|
|||
it('should not observe raw data', () => { |
|||
let dummy |
|||
const key = {} |
|||
const map = observable(new Map()) |
|||
autorun(() => (dummy = unwrap(map).get('key'))) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
map.set(key, 'Hello') |
|||
expect(dummy).toBe(undefined) |
|||
map.delete(key) |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
}) |
@ -0,0 +1,79 @@ |
|||
import { observable, isObservable, autorun, unwrap } from '../../src' |
|||
|
|||
describe('WeakSet', () => { |
|||
it('instanceof', () => { |
|||
const original = new Set() |
|||
const observed = observable(original) |
|||
expect(isObservable(observed)).toBe(true) |
|||
expect(original instanceof Set).toBe(true) |
|||
expect(observed instanceof Set).toBe(true) |
|||
}) |
|||
|
|||
it('should observe mutations', () => { |
|||
let dummy |
|||
const value = {} |
|||
const set = observable(new WeakSet()) |
|||
autorun(() => (dummy = set.has(value))) |
|||
|
|||
expect(dummy).toBe(false) |
|||
set.add(value) |
|||
expect(dummy).toBe(true) |
|||
set.delete(value) |
|||
expect(dummy).toBe(false) |
|||
}) |
|||
|
|||
it('should not observe custom property mutations', () => { |
|||
let dummy |
|||
const set: any = observable(new WeakSet()) |
|||
autorun(() => (dummy = set.customProp)) |
|||
|
|||
expect(dummy).toBe(undefined) |
|||
set.customProp = 'Hello World' |
|||
expect(dummy).toBe(undefined) |
|||
}) |
|||
|
|||
it('should not observe non value changing mutations', () => { |
|||
let dummy |
|||
const value = {} |
|||
const set = observable(new WeakSet()) |
|||
const setSpy = jest.fn(() => (dummy = set.has(value))) |
|||
autorun(setSpy) |
|||
|
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(1) |
|||
set.add(value) |
|||
expect(dummy).toBe(true) |
|||
expect(setSpy).toHaveBeenCalledTimes(2) |
|||
set.add(value) |
|||
expect(dummy).toBe(true) |
|||
expect(setSpy).toHaveBeenCalledTimes(2) |
|||
set.delete(value) |
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(3) |
|||
set.delete(value) |
|||
expect(dummy).toBe(false) |
|||
expect(setSpy).toHaveBeenCalledTimes(3) |
|||
}) |
|||
|
|||
it('should not observe raw data', () => { |
|||
const value = {} |
|||
let dummy |
|||
const set = observable(new WeakSet()) |
|||
autorun(() => (dummy = unwrap(set).has(value))) |
|||
|
|||
expect(dummy).toBe(false) |
|||
set.add(value) |
|||
expect(dummy).toBe(false) |
|||
}) |
|||
|
|||
it('should not be triggered by raw mutations', () => { |
|||
const value = {} |
|||
let dummy |
|||
const set = observable(new WeakSet()) |
|||
autorun(() => (dummy = set.has(value))) |
|||
|
|||
expect(dummy).toBe(false) |
|||
unwrap(set).add(value) |
|||
expect(dummy).toBe(false) |
|||
}) |
|||
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue