@noego/app 0.0.7 → 0.0.10

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.
@@ -0,0 +1,164 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import path from 'node:path';
4
+
5
+ /**
6
+ * These are the SAME functions used in bootstrap.js
7
+ * We're testing them in isolation with real project data
8
+ */
9
+ function calculateComponentPaths(config) {
10
+ if (!config.client?.componentDir_abs) {
11
+ return {
12
+ component_dir: '.app/ssr',
13
+ componentDir_abs: '.app/ssr',
14
+ component_suffix: null
15
+ };
16
+ }
17
+
18
+ const uiRootAbs = config.client.main_abs ? path.dirname(config.client.main_abs) : config.root;
19
+ const relativeFromUiRoot = path.relative(uiRootAbs, config.client.componentDir_abs);
20
+
21
+ return {
22
+ component_dir: path.join('.app/ssr', relativeFromUiRoot),
23
+ componentDir_abs: path.join('.app/ssr', relativeFromUiRoot),
24
+ component_suffix: relativeFromUiRoot || null
25
+ };
26
+ }
27
+
28
+ function calculateAssetFallback(componentSuffix) {
29
+ if (!componentSuffix) {
30
+ return null;
31
+ }
32
+ return path.join('.app/assets', componentSuffix);
33
+ }
34
+
35
+ /**
36
+ * Test with REAL project configurations
37
+ */
38
+ test('markdown_view: componentDir in subfolder', () => {
39
+ // Actual values from markdown_view/hammer.config.yml
40
+ const config = {
41
+ root: '/Users/shavauhngabay/dev/markdown_view',
42
+ client: {
43
+ main_abs: '/Users/shavauhngabay/dev/markdown_view/frontend/frontend.ts',
44
+ componentDir_abs: '/Users/shavauhngabay/dev/markdown_view/frontend/components'
45
+ }
46
+ };
47
+
48
+ const result = calculateComponentPaths(config);
49
+ const assetFallback = calculateAssetFallback(result.component_suffix);
50
+
51
+ console.log('markdown_view result:', result);
52
+ console.log('markdown_view asset fallback:', assetFallback);
53
+
54
+ // Expected: components are nested in 'components' subfolder
55
+ assert.strictEqual(result.component_dir, '.app/ssr/components', 'component_dir should be .app/ssr/components');
56
+ assert.strictEqual(result.component_suffix, 'components', 'component_suffix should be components');
57
+ assert.strictEqual(assetFallback, '.app/assets/components', 'asset fallback should be .app/assets/components');
58
+ });
59
+
60
+ test('noblelaw/liftlog: no explicit componentDir', () => {
61
+ // When componentDir is not explicitly set, it defaults to UI root
62
+ const config = {
63
+ root: '/Users/shavauhngabay/dev/noblelaw',
64
+ client: {
65
+ main_abs: '/Users/shavauhngabay/dev/noblelaw/ui/main.ts',
66
+ componentDir_abs: null
67
+ }
68
+ };
69
+
70
+ const result = calculateComponentPaths(config);
71
+ const assetFallback = calculateAssetFallback(result.component_suffix);
72
+
73
+ console.log('noblelaw result:', result);
74
+ console.log('noblelaw asset fallback:', assetFallback);
75
+
76
+ // Expected: no suffix, components at root
77
+ assert.strictEqual(result.component_dir, '.app/ssr', 'component_dir should be .app/ssr');
78
+ assert.strictEqual(result.component_suffix, null, 'component_suffix should be null');
79
+ assert.strictEqual(assetFallback, null, 'asset fallback should be null');
80
+ });
81
+
82
+ test('deeply nested componentDir', () => {
83
+ // Edge case: deeply nested component directory
84
+ const config = {
85
+ root: '/Users/test/project',
86
+ client: {
87
+ main_abs: '/Users/test/project/src/ui/main.ts',
88
+ componentDir_abs: '/Users/test/project/src/ui/components/shared'
89
+ }
90
+ };
91
+
92
+ const result = calculateComponentPaths(config);
93
+ const assetFallback = calculateAssetFallback(result.component_suffix);
94
+
95
+ console.log('nested result:', result);
96
+ console.log('nested asset fallback:', assetFallback);
97
+
98
+ // Expected: preserves nested structure
99
+ assert.strictEqual(result.component_dir, '.app/ssr/components/shared', 'component_dir should preserve nested path');
100
+ assert.strictEqual(result.component_suffix, 'components/shared', 'component_suffix should be components/shared');
101
+ assert.strictEqual(assetFallback, '.app/assets/components/shared', 'asset fallback should match nested structure');
102
+ });
103
+
104
+ /**
105
+ * Test the ACTUAL bug: verify that when we pass component_dir to client.js,
106
+ * we can extract the suffix without complex string manipulation
107
+ */
108
+ test('verify simple suffix extraction', () => {
109
+ const testCases = [
110
+ { component_dir: '.app/ssr/components', expected: 'components' },
111
+ { component_dir: '.app/ssr', expected: null },
112
+ { component_dir: '.app/ssr/components/shared', expected: 'components/shared' }
113
+ ];
114
+
115
+ testCases.forEach(({ component_dir, expected }) => {
116
+ // This is what we should store in the config
117
+ const suffix = component_dir.replace('.app/ssr', '').replace(/^\//, '') || null;
118
+
119
+ console.log(`component_dir: ${component_dir} → suffix: ${suffix}`);
120
+
121
+ assert.strictEqual(
122
+ suffix,
123
+ expected,
124
+ `component_dir ${component_dir} should extract suffix ${expected}`
125
+ );
126
+ });
127
+ });
128
+
129
+ /**
130
+ * Integration test: Full pipeline from config → bootstrap → runtime
131
+ */
132
+ test('full pipeline: markdown_view', () => {
133
+ // Step 1: Config input
134
+ const configInput = {
135
+ root: '/Users/shavauhngabay/dev/markdown_view',
136
+ client: {
137
+ main_abs: '/Users/shavauhngabay/dev/markdown_view/frontend/frontend.ts',
138
+ componentDir_abs: '/Users/shavauhngabay/dev/markdown_view/frontend/components'
139
+ }
140
+ };
141
+
142
+ // Step 2: Bootstrap calculation
143
+ const bootstrapResult = calculateComponentPaths(configInput);
144
+
145
+ // Step 3: Runtime usage (what client.js needs)
146
+ const runtimeAssetFallback = calculateAssetFallback(bootstrapResult.component_suffix);
147
+
148
+ console.log('=== Full Pipeline Test ===');
149
+ console.log('Config input:', configInput.client);
150
+ console.log('Bootstrap result:', bootstrapResult);
151
+ console.log('Runtime asset fallback:', runtimeAssetFallback);
152
+
153
+ // Verify the entire flow
154
+ assert.strictEqual(bootstrapResult.component_dir, '.app/ssr/components');
155
+ assert.strictEqual(bootstrapResult.component_suffix, 'components');
156
+ assert.strictEqual(runtimeAssetFallback, '.app/assets/components');
157
+
158
+ // This is what we need to mount in Express
159
+ console.log('\n✅ Express should mount:');
160
+ console.log(' Primary: .app/assets at /assets');
161
+ console.log(` Fallback: ${runtimeAssetFallback} at /assets`);
162
+ console.log('\n✅ This allows browser to request: /assets/layout/root.js');
163
+ console.log(` And Express finds it at: ${runtimeAssetFallback}/layout/root.js`);
164
+ });