import { test } from 'uvu' import { equal } from 'uvu/assert' import { type Be, be_, be__ctx_, be__has_, be__val_, type Ctx, ctx__delete, ctx__set, globalThis__be_, type MapCtx } from '../be_/index.js' import { ctx__new } from '../ctx/index.js' test.after(()=>{ delete (globalThis as { root_be?:Be }).root_be }) test('globalThis__be_', ()=>{ const ctx = ctx__new() const be = globalThis__be_(()=>1, { id: 'root_be' }) equal(be(ctx), 1) const be2 = globalThis__be_(()=>1, { id: 'root_be' }) equal(be2(ctx), 1) }) test('be_|Map', ()=>{ const ctx = ctx__new() let incrementer_num = 0 const incrementer = ()=>++incrementer_num const root_ = be_(()=>{ console.debug('root_|debug|1') return incrementer() }, { id: 'root_' }) const child_ = be_(ctx=>{ console.debug('child_|debug|1') return root_(ctx) + incrementer() }, { id: 'child_' }) const child1_ = be_(ctx=>root_(ctx) + child_(ctx), { id: 'child1_' }) equal(root_(ctx), 1) equal(ctx.get('root_'), 1) equal(child_(ctx), 3) equal(ctx.get('child_'), 3) equal(child1_(ctx), 4) equal(ctx.get('child1_'), 4) }) test('be_|simple array', ()=>{ const ctx0 = ctx__new() const ctx1 = ctx__new() const ctx = [ctx0, ctx1] const root_ = be_(()=>1, { id: 'root_' }) equal(root_(ctx1), 1) equal(root_(ctx), 1) equal(ctx0.has(root_.id), false) equal(ctx1.has(root_.id), true) const child_ = be_(ctx=>root_(ctx) + 1, { id: 'child_' }) equal(child_(ctx), 2) equal(ctx0.has(child_.id), true) equal(ctx1.has(child_.id), false) }) test('be_|nested array', ()=>{ const ctx0 = ctx__new() const ctx1 = ctx__new() const ctx2 = ctx__new() const ctx3 = ctx__new() const ctx = [[[ctx0], ctx1], [ctx2, ctx3]] const root_ = be_(()=>1, { id: 'root_' }) equal(root_(ctx3), 1) equal(root_(ctx), 1) equal(ctx0.has(root_.id), false) equal(ctx1.has(root_.id), false) equal(ctx2.has(root_.id), false) equal(ctx3.has(root_.id), true) const child_ = be_(ctx=>root_(ctx) + 1, { id: 'child_' }) equal(child_(ctx), 2) equal(ctx0.has(child_.id), true) equal(ctx1.has(child_.id), false) equal(ctx2.has(child_.id), false) equal(ctx3.has(child_.id), false) }) test('be_|is_source_', ()=>{ const ctx0 = ctx__new() const ctx1 = ctx__new() ctx1.set('matching', true) const ctx = [ctx0, ctx1] const be__ctx_a:Ctx[] = [] const root_ = be_(ctx=>{ be__ctx_a.push(ctx) return 1 }, { is_source_: map_ctx=>!!map_ctx.get('matching'), id: 'root_' }) equal(root_(ctx), 1) equal(be__ctx_a, [[ctx0, ctx1]]) equal(ctx0.has(root_.id), false) equal(ctx1.has(root_.id), true) }) test('be_|Ctx generic type', ()=>{ const valid_ctx = ctx__new() as test_ctx_T const val_ = be_(()=>true, { id: 'val_' }) val_(valid_ctx) // val_(ctx_()) // type error }) test('be_|Ctx|NestedMapCtx', ()=>{ const ctx0 = ctx__new() const ctx1 = ctx__new() ctx1.set('matching', true) const ctx = [ctx0, ctx1] const nested__ctx_ = be_(ctx=>[ctx], { id: 'nested__ctx_' }) equal(nested__ctx_(ctx), [[ctx0, ctx1]]) }) test('be_|circular dependency', ()=>{ const be0:Be = be_(ctx=>be1(ctx)) const be1:Be = be_(ctx=>be0(ctx)) const ctx = ctx__new() equal(be0(ctx), 'cir') equal(be1(ctx), 'cir') }) test('ctx__set', ()=>{ const ctx0 = ctx__new() ctx__set(ctx0, 'key', 1) equal(ctx0.get('key'), 1) const ctx1 = ctx__new() const ctx_a = [ctx1, ctx0] ctx__set(ctx_a, 'key', 2, (map_ctx:MapCtx)=>map_ctx.get('key') != null) equal(ctx0.get('key'), 2) equal(ctx1.has('key'), false) }) test('ctx__delete|id', ()=>{ const ctx0 = ctx__new() ctx__delete(ctx0, 'key') equal(ctx0.has('key'), false) ctx0.set('key', true) equal(ctx0.get('key'), true) ctx__delete(ctx0, 'key') equal(ctx0.has('key'), false) const ctx1 = ctx__new() const nested__ctx = [ctx0, ctx1] ctx0.set('key', true) ctx1.set('key', true) equal(ctx0.get('key'), true) equal(ctx1.get('key'), true) ctx__delete(nested__ctx, 'key') equal(ctx0.has('key'), false) equal(ctx1.has('key'), false) }) test('ctx__delete|be', ()=>{ const ctx0 = ctx__new() const num_ = be_(()=>1) ctx__delete(ctx0, num_) equal(ctx0.has(num_.id), false) num_(ctx0) equal(ctx0.has(num_.id), true) ctx__delete(ctx0, num_) equal(ctx0.has(num_.id), false) num_(ctx0) equal(ctx0.has(num_.id), true) ctx__delete(ctx0, num_) equal(ctx0.has(num_.id), false) const ctx1 = ctx__new() ctx1.set('ctx1', true) const nested__ctx = [ctx0, ctx1] num_(ctx0) num_(ctx1) equal(ctx0.has(num_.id), true) equal(ctx1.has(num_.id), true) ctx__delete(nested__ctx, num_) equal(ctx0.has(num_.id), false) equal(ctx1.has(num_.id), false) num_(ctx0) num_(ctx1) equal(ctx0.has(num_.id), true) equal(ctx1.has(num_.id), true) ctx__delete(nested__ctx, num_) equal(ctx0.has(num_.id), false) equal(ctx1.has(num_.id), false) const is_source__num_ = be_(()=>1, { is_source_: ctx=>!!ctx.get('ctx1') }) is_source__num_(nested__ctx) equal(ctx0.has(is_source__num_.id), false) equal(ctx1.has(is_source__num_.id), true) ctx__delete(nested__ctx, is_source__num_) equal(ctx0.has(is_source__num_.id), false) equal(ctx1.has(is_source__num_.id), false) is_source__num_(nested__ctx) equal(ctx0.has(is_source__num_.id), false) equal(ctx1.has(is_source__num_.id), true) ctx__delete(nested__ctx, is_source__num_) equal(ctx0.has(is_source__num_.id), false) equal(ctx1.has(is_source__num_.id), false) }) test('be__has_', ()=>{ const ctx0 = ctx__new() ctx__delete(ctx0, 'key') equal(be__has_('key', ctx0), false) ctx0.set('key', true) equal(be__has_('key', ctx0), true) ctx__delete(ctx0, 'key') equal(be__has_('key', ctx0), false) const ctx1 = ctx__new() const nested__ctx = [ctx0, ctx1] ctx1.set('key', true) equal(be__has_('key', nested__ctx), true) }) test('be__ctx_', ()=>{ const ctx0 = ctx__new() ctx__delete(ctx0, 'key') equal(be__ctx_('key', ctx0), undefined) ctx0.set('key', true) equal(be__ctx_('key', ctx0), ctx0) ctx__delete(ctx0, 'key') equal(be__ctx_('key', ctx0), undefined) const ctx1 = ctx__new() const nested__ctx = [ctx0, ctx1] ctx1.set('key', true) equal(be__ctx_('key', nested__ctx), ctx1) }) test('be__val_', ()=>{ const ctx = ctx__new() const val_ = be_(()=>true, { id: 'val_' }) equal(val_(ctx), true) equal(ctx.get(val_.id), true) equal(be__val_(val_, ctx), true) ctx__set(ctx, val_, false) equal(val_(ctx), false) equal(be__val_(val_, ctx), false) }) test.run() declare const test_ctx_sym:unique symbol type test_ctx_T = Ctx&{ [test_ctx_sym]:unknown }