@everystate/test 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,6 +35,21 @@ test('counter increments', () => {
35
35
  - **Type extraction** Infer types from state
36
36
  - **Fast** 100 tests in ~0.5ms
37
37
 
38
+ ## Ecosystem
39
+
40
+ | Package | Description | License |
41
+ |---|---|---|
42
+ | [@everystate/aliases](https://www.npmjs.com/package/@everystate/aliases) | Ergonomic single-character and short-name DOM aliases for vanilla JS | MIT |
43
+ | [@everystate/core](https://www.npmjs.com/package/@everystate/core) | Path-based state management with wildcard subscriptions and async support. Core state engine (you are here). | MIT |
44
+ | [@everystate/css](https://www.npmjs.com/package/@everystate/css) | Reactive CSSOM engine: design tokens, typed validation, WCAG enforcement, all via path-based state | MIT |
45
+ | [@everystate/examples](https://www.npmjs.com/package/@everystate/examples) | Example applications and patterns | MIT |
46
+ | [@everystate/perf](https://www.npmjs.com/package/@everystate/perf) | Performance monitoring overlay | MIT |
47
+ | [@everystate/react](https://www.npmjs.com/package/@everystate/react) | React hooks adapter: `usePath`, `useIntent`, `useAsync` hooks and `EveryStateProvider` | MIT |
48
+ | [@everystate/renderer](https://www.npmjs.com/package/@everystate/renderer) | Direct-binding reactive renderer: `bind-*`, `set`, `each` attributes. Zero build step | Proprietary |
49
+ | [@everystate/router](https://www.npmjs.com/package/@everystate/router) | SPA routing as state | MIT |
50
+ | [@everystate/test](https://www.npmjs.com/package/@everystate/test) | Event-sequence testing for EveryState stores. Zero dependency. | Proprietary |
51
+ | [@everystate/view](https://www.npmjs.com/package/@everystate/view) | State-driven view: DOMless resolve + surgical DOM projector. View tree as first-class state | MIT |
52
+
38
53
  ## License
39
54
 
40
55
  Proprietary - See LICENSE.md for details.
package/eventTest.js ADDED
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @everystate/test: Event-Sequence Testing for EveryState
3
+ *
4
+ * Copyright (c) 2026 Ajdin Imsirovic. MIT License.
5
+ *
6
+ * Provides TDD-style testing with type extraction capabilities.
7
+ */
8
+
9
+ import { createEveryState } from '@everystate/core';
10
+
11
+ export function createEventTest(initialState = {}) {
12
+ const store = createEveryState(initialState);
13
+ const eventLog = [];
14
+ const typeAssertions = [];
15
+
16
+ // Spy on all events
17
+ store.subscribe('*', (detail) => {
18
+ const { path, value } = detail;
19
+ eventLog.push({ timestamp: Date.now(), path, value });
20
+ });
21
+
22
+ const api = {
23
+ store,
24
+
25
+ // Trigger a state change
26
+ trigger(path, value) {
27
+ store.set(path, value);
28
+ return this;
29
+ },
30
+
31
+ // Assert exact value
32
+ assertPath(path, expected) {
33
+ const actual = store.get(path);
34
+ if (JSON.stringify(actual) !== JSON.stringify(expected)) {
35
+ throw new Error(`Expected ${path} to be ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
36
+ }
37
+ return this;
38
+ },
39
+
40
+ // Assert type (for type generation)
41
+ assertType(path, expectedType) {
42
+ const actual = store.get(path);
43
+ const actualType = typeof actual;
44
+
45
+ if (actualType !== expectedType) {
46
+ throw new Error(`Expected ${path} to be type ${expectedType}, got ${actualType}`);
47
+ }
48
+
49
+ // Store for type generation
50
+ typeAssertions.push({ path, type: expectedType });
51
+ return this;
52
+ },
53
+
54
+ // Assert array with element shape (for type generation)
55
+ assertArrayOf(path, elementShape) {
56
+ const actual = store.get(path);
57
+
58
+ if (!Array.isArray(actual)) {
59
+ throw new Error(`Expected ${path} to be an array, got ${typeof actual}`);
60
+ }
61
+
62
+ // Validate first element matches shape (if array not empty)
63
+ if (actual.length > 0) {
64
+ validateShape(actual[0], elementShape, path);
65
+ }
66
+
67
+ // Store for type generation
68
+ typeAssertions.push({ path, type: 'array', elementShape });
69
+ return this;
70
+ },
71
+
72
+ // Assert object shape (for type generation)
73
+ assertShape(path, objectShape) {
74
+ const actual = store.get(path);
75
+
76
+ if (typeof actual !== 'object' || actual === null || Array.isArray(actual)) {
77
+ throw new Error(`Expected ${path} to be an object, got ${typeof actual}`);
78
+ }
79
+
80
+ validateShape(actual, objectShape, path);
81
+
82
+ // Store for type generation
83
+ typeAssertions.push({ path, type: 'object', shape: objectShape });
84
+ return this;
85
+ },
86
+
87
+ // Assert array length
88
+ assertArrayLength(path, expectedLength) {
89
+ const actual = store.get(path);
90
+
91
+ if (!Array.isArray(actual)) {
92
+ throw new Error(`Expected ${path} to be an array`);
93
+ }
94
+
95
+ if (actual.length !== expectedLength) {
96
+ throw new Error(`Expected ${path} to have length ${expectedLength}, got ${actual.length}`);
97
+ }
98
+
99
+ return this;
100
+ },
101
+
102
+ // Assert event fired N times
103
+ assertEventFired(path, times) {
104
+ const count = eventLog.filter(e => e.path === path).length;
105
+ if (times !== undefined && count !== times) {
106
+ throw new Error(`Expected ${path} to fire ${times} times, fired ${count}`);
107
+ }
108
+ return this;
109
+ },
110
+
111
+ // Get event log
112
+ getEventLog() {
113
+ return [...eventLog];
114
+ },
115
+
116
+ // Get type assertions (for type generation)
117
+ getTypeAssertions() {
118
+ return [...typeAssertions];
119
+ }
120
+ };
121
+
122
+ return api;
123
+ }
124
+
125
+ // Helper to validate object shape
126
+ function validateShape(actual, shape, path) {
127
+ for (const [key, expectedType] of Object.entries(shape)) {
128
+ if (!(key in actual)) {
129
+ throw new Error(`Expected ${path} to have property ${key}`);
130
+ }
131
+
132
+ const actualValue = actual[key];
133
+
134
+ // Handle nested objects
135
+ if (typeof expectedType === 'object' && !Array.isArray(expectedType)) {
136
+ validateShape(actualValue, expectedType, `${path}.${key}`);
137
+ } else {
138
+ // Primitive type check
139
+ const actualType = typeof actualValue;
140
+ if (actualType !== expectedType) {
141
+ throw new Error(`Expected ${path}.${key} to be type ${expectedType}, got ${actualType}`);
142
+ }
143
+ }
144
+ }
145
+ }
146
+
147
+ // Simple test runner
148
+ export function test(name, fn) {
149
+ try {
150
+ fn();
151
+ console.log(`\u2713 ${name}`);
152
+ return true;
153
+ } catch (error) {
154
+ console.error(`\u2717 ${name}`);
155
+ console.error(` ${error.message}`);
156
+ return false;
157
+ }
158
+ }
159
+
160
+ // Run multiple tests
161
+ export function runTests(tests) {
162
+ console.log('\n\uD83E\uDDEA Running tests...\n');
163
+
164
+ let passed = 0;
165
+ let failed = 0;
166
+
167
+ for (const [name, fn] of Object.entries(tests)) {
168
+ if (test(name, fn)) {
169
+ passed++;
170
+ } else {
171
+ failed++;
172
+ }
173
+ }
174
+
175
+ console.log(`\n\uD83D\uDCCA Results: ${passed} passed, ${failed} failed\n`);
176
+
177
+ return { passed, failed };
178
+ }
package/index.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @everystate/test
3
+ *
4
+ * Event-sequence testing for EveryState.
5
+ * TDD-style testing with type extraction capabilities.
6
+ */
7
+
8
+ import type { EveryStateStore } from '@everystate/core';
9
+
10
+ export interface TestCase {
11
+ name: string;
12
+ fn: (store: EveryStateStore) => void | Promise<void>;
13
+ }
14
+
15
+ export interface TestResult {
16
+ name: string;
17
+ passed: boolean;
18
+ error?: Error;
19
+ duration: number;
20
+ }
21
+
22
+ export interface TestSuite {
23
+ /** Add a test case */
24
+ add(name: string, fn: (store: EveryStateStore) => void | Promise<void>): void;
25
+ /** Run all registered tests */
26
+ run(): Promise<TestResult[]>;
27
+ /** Get results summary */
28
+ results(): TestResult[];
29
+ }
30
+
31
+ /**
32
+ * Create a test suite for event-sequence testing.
33
+ */
34
+ export function createEventTest(store: EveryStateStore): TestSuite;
35
+
36
+ /**
37
+ * Define a single test case (shorthand).
38
+ */
39
+ export function test(name: string, fn: (store: EveryStateStore) => void | Promise<void>): TestCase;
40
+
41
+ /**
42
+ * Run an array of test cases against a store.
43
+ */
44
+ export function runTests(store: EveryStateStore, tests: TestCase[]): Promise<TestResult[]>;
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * @everystate/test
3
3
  *
4
- * EveryState wrapper for @uistate/event-test
5
- * Re-exports all functionality from the underlying @uistate/event-test package
4
+ * Event-sequence testing for EveryState.
5
+ * TDD-style testing with type extraction capabilities.
6
6
  */
7
7
 
8
- export * from '@uistate/event-test';
8
+ export { createEventTest, test, runTests } from './eventTest.js';
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@everystate/test",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "EveryState Test: Testing library with TDD-style assertions and event-sequence tracking",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
+ "types": "index.d.ts",
7
8
  "keywords": [
8
9
  "everystate",
9
10
  "testing",
@@ -25,10 +26,9 @@
25
26
  },
26
27
  "files": [
27
28
  "index.js",
29
+ "eventTest.js",
30
+ "index.d.ts",
28
31
  "README.md",
29
32
  "LICENSE.md"
30
- ],
31
- "dependencies": {
32
- "@uistate/event-test": "^1.0.1"
33
- }
33
+ ]
34
34
  }