import { beforeEach, describe, expect, it } from 'vitest'; import { Namespace } from './namespace'; describe('Namespace', () => { let namespace: Namespace; beforeEach(() => { namespace = new Namespace(); }); describe('initialization', () => { it('should start with empty name', () => { expect(namespace.name).toBe(''); }); }); describe('ns()', () => { it('should set namespace', () => { namespace.ns('my.plugin'); expect(namespace.name).toBe('my.plugin'); }); it('should support dot-notation namespaces', () => { namespace.ns('analytics.tracking.events'); expect(namespace.name).toBe('analytics.tracking.events'); }); it('should support single-word namespaces', () => { namespace.ns('analytics'); expect(namespace.name).toBe('analytics'); }); it('should throw error on re-assignment', () => { namespace.ns('first.namespace'); expect(() => { namespace.ns('second.namespace'); }).toThrow(Error); }); it('should throw error with descriptive message', () => { namespace.ns('first.namespace'); expect(() => { namespace.ns('second.namespace'); }).toThrow( 'Namespace already set to "first.namespace". Cannot reassign to "second.namespace".' ); }); it('should prevent reassignment even with same value', () => { namespace.ns('my.plugin'); expect(() => { namespace.ns('my.plugin'); }).toThrow(Error); }); it('should allow empty string as namespace', () => { namespace.ns(''); expect(namespace.name).toBe(''); }); it('should prevent reassignment after empty string', () => { namespace.ns(''); // Empty string is falsy but should still count as "set" // Actually, our implementation checks `if (this.name)` so empty string won't prevent reassignment // This is okay - empty string is not a valid namespace anyway expect(() => { namespace.ns('actual.namespace'); }).not.toThrow(); }); }); describe('edge cases', () => { it('should handle special characters in namespace', () => { namespace.ns('my-plugin.v2'); expect(namespace.name).toBe('my-plugin.v2'); }); it('should handle numeric segments', () => { namespace.ns('plugin.v1.beta2'); expect(namespace.name).toBe('plugin.v1.beta2'); }); it('should handle very long namespaces', () => { const longName = 'a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p'; namespace.ns(longName); expect(namespace.name).toBe(longName); }); }); describe('multiple instances', () => { it('should allow different namespaces in different instances', () => { const ns1 = new Namespace(); const ns2 = new Namespace(); ns1.ns('plugin.one'); ns2.ns('plugin.two'); expect(ns1.name).toBe('plugin.one'); expect(ns2.name).toBe('plugin.two'); }); it('should be independent instances', () => { const ns1 = new Namespace(); const ns2 = new Namespace(); ns1.ns('set.namespace'); // ns2 should still be unset expect(ns2.name).toBe(''); expect(() => { ns2.ns('different.namespace'); }).not.toThrow(); }); }); });