/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
compiler/packages/make-read-only-util/src/__tests__/makeReadOnly-test.ts
166 строк
5 KB
Jan Kassens
Compiler: unfork prettier config (#30205)
19 июл 2024, 00:00
Не верифицирован
19 июл 2024, 00:00
fd2b3e1
Код
Авторство
О чём код?
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import buildMakeReadOnly from '../makeReadOnly'; describe('makeReadOnly', () => { let logger: jest.Func; let makeReadOnly: <T>(value: T, source: string) => T; beforeEach(() => { logger = jest.fn(); makeReadOnly = buildMakeReadOnly(logger, []); }); describe('Tracking mutations', () => { it('can be called with all primitives', () => { const a = 5; const b = true; const c = null; expect(makeReadOnly(a, 'test1')).toBe(a); expect(makeReadOnly(b, 'test1')).toBe(b); expect(makeReadOnly(c, 'test1')).toBe(c); }); it('retains referential equality', () => { const valA = {}; const valB = {a: valA, _: valA}; const o = {a: valA, b: valB, c: 'c'}; expect(makeReadOnly(o, 'test2')).toBe(o); expect(makeReadOnly(o.a, 'test2')).toBe(valA); expect(makeReadOnly(o.b, 'test2')).toBe(valB); expect(makeReadOnly(o.b.a, 'test2')).toBe(valA); expect(makeReadOnly(o.b._, 'test2')).toBe(valA); expect(makeReadOnly(o.c, 'test2')).toBe('c'); }); it('deals with cyclic references', () => { const o: any = {}; o.self_ref = o; expect(makeReadOnly(o, 'test3')).toBe(o); expect(makeReadOnly(o.self_ref, 'test3')).toBe(o); }); it('logs direct interior mutability', () => { const o = {a: 0}; makeReadOnly(o, 'test4'); o.a = 42; expect(logger).toBeCalledWith('FORGET_MUTATE_IMMUT', 'test4', 'a', 42); }); it('tracks changes to known RO properties', () => { const o: any = {a: {}}; makeReadOnly(o, 'test5'); o.a = 42; expect(logger).toBeCalledWith('FORGET_MUTATE_IMMUT', 'test5', 'a', 42); expect(o.a).toBe(42); const newVal = {x: 0}; o.a = newVal; expect(logger).toBeCalledWith( 'FORGET_MUTATE_IMMUT', 'test5', 'a', newVal, ); expect(o.a).toBe(newVal); }); it('logs aliased mutations', () => { const o: any = {a: {x: 4}}; const alias = o; makeReadOnly(o, 'test6'); const newVal = {}; alias.a = newVal; expect(logger).toBeCalledWith( 'FORGET_MUTATE_IMMUT', 'test6', 'a', newVal, ); expect(o.a).toBe(newVal); }); it('logs transitive interior mutability', () => { const o: any = {a: {x: 0}}; makeReadOnly(o, 'test7'); o.a.x = 42; expect(logger).toBeCalledWith('FORGET_MUTATE_IMMUT', 'test7', 'x', 42); }); describe('todo', () => { it('does not track newly added or deleted vals if makeReadOnly is only called once', () => { // this is a limitation of the current "proxy" approach, // which overwrites object properties with getters and setters const x: any = {a: {}}; makeReadOnly(x, 'test8'); delete x.a; x.b = 0; expect(logger).toBeCalledTimes(0); }); it('does not log aliased indirect mutations', () => { // this could be easily implemented by making caching eager const innerObj = {x: 0}; const o = {a: innerObj}; makeReadOnly(o, 'test9'); innerObj.x = 42; expect(o.a.x).toBe(42); const o1 = {a: {x: 0}}; const innerObj1 = o1.a; makeReadOnly(o1, 'test9'); innerObj1.x = 42; expect(o1.a.x).toBe(42); expect(logger).toBeCalledTimes(0); }); it('does not track objects with getter/setters', () => { let backedX: string | null = null; const o = { set val(val: string | null) { backedX = val; }, get val(): string | null { return backedX; }, }; expect(makeReadOnly(o, 'test10')).toBe(o); expect(makeReadOnly(o.val, 'test10')).toBe(null); o.val = '40'; expect(logger).toBeCalledTimes(0); }); }); }); describe('Tracking adding or deleting properties', () => { it('tracks new properties added between calls to makeReadOnly', () => { const o: any = {}; makeReadOnly(o, 'test11'); o.a = 'new value'; makeReadOnly(o, 'test11'); expect(logger).toBeCalledWith('FORGET_ADD_PROP_IMMUT', 'test11', 'a'); }); it('tracks properties deleted between calls to makeReadOnly', () => { const o: any = {a: 0}; makeReadOnly(o, 'test12'); delete o.a; makeReadOnly(o, 'test12'); expect(logger).toBeCalledWith('FORGET_DELETE_PROP_IMMUT', 'test12', 'a'); }); // it("tracks properties deleted and re-added between calls to makeReadOnly", () => { // const o: any = { a: 0 }; // makeReadOnly(o); // delete o.a; // o.a = {}; // makeReadOnly(o); // expect(logger).toBeCalledWith("FORGET_CHANGE_PROP_IMMUT", "a"); // }); }); });