UNPKG

context

Version:

Lightweight context propagation for JavaScript and TypeScript. Create a scoped storage object, run code inside it, and read the active value anywhere down the call stack - without depending on React.

105 lines (90 loc) 3 kB
import { describe, it, expect, beforeEach } from 'vitest'; import { createContext, CtxApi } from '../context'; describe('Context', () => { let ctx: CtxApi<any>; beforeEach(() => { ctx = createContext(); }); describe('Exposed Methods', () => { it('should have a use method', () => { expect(ctx.use).toBeInstanceOf(Function); }); it('should have a run method', () => { expect(ctx.run).toBeInstanceOf(Function); }); }); describe('use', () => { describe('When not inside of an active context', () => { describe('When a default value was not provided', () => { it('should return undefined', () => { expect(ctx.use()).toBeUndefined(); }); }); describe('When a default value was provided', () => { beforeEach(() => { ctx = createContext('i am the default value!'); }); it('should return the default value', () => { expect(ctx.use()).toBe('i am the default value!'); }); }); }); }); describe('useX', () => { describe('When not inside of an active context', () => { it('Should throw an error', () => { expect(() => { ctx.useX(); }).toThrow('Not inside of a running context.'); }); it('Should throw an error with a custom message when passed', () => { expect(() => { ctx.useX('i am the error message!'); }).toThrow('i am the error message!'); }); describe('When a default value was provided', () => { beforeEach(() => { ctx = createContext('i am the default value!'); }); it('Should disregard default value', () => { expect(() => { ctx.useX(); }).toThrow('Not inside of a running context.'); }); }); }); }); describe('run', () => { describe('It should set the current context value to the passed value', () => { it('should set the current context value to the passed value', () => { const value = { some: 'object' }; ctx.run(value, () => { expect(ctx.use()).toBe(value); }); }); }); describe('When nesting run calls', () => { it("sets each layer's context with its respective value", () => { const value_a = { some: 'object' }; ctx.run(value_a, () => { expect(ctx.use()).toBe(value_a); const value_b = { another: 'obj' }; ctx.run(value_b, () => { expect(ctx.use()).toBe(value_b); }); }); }); it('Restores the previous context value when exiting a context layer', () => { const value_a = { some: 'object' }; ctx.run(value_a, () => { const value_b = { another: 'obj' }; ctx.run(value_b, () => { expect(ctx.use()).toBe(value_b); }); expect(ctx.use()).toBe(value_a); }); expect(ctx.use()).toBeUndefined(); }); }); }); });