@garyr/pt-cli 0.30.0 → 0.30.1

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/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@garyr/pt-cli",
3
- "version": "0.30.0",
3
+ "version": "0.30.1",
4
4
  "description": "Project Template CLI - Learn structures and initialize projects",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
- "pt": "./dist/index.js"
7
+ "pt": "dist/index.js"
8
8
  },
9
9
  "type": "module",
10
10
  "scripts": {
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "direct-json-test",
3
+ "description": "A mock template for direct JSON scaffolding test",
4
+ "folders": [
5
+ {
6
+ "name": "src",
7
+ "info": "contains sources",
8
+ "children": [
9
+ {
10
+ "name": "components",
11
+ "info": "reusable components"
12
+ },
13
+ {
14
+ "name": "utils",
15
+ "info": "utility functions"
16
+ }
17
+ ]
18
+ },
19
+ {
20
+ "name": "docs",
21
+ "info": "documentation folder"
22
+ }
23
+ ]
24
+ }
@@ -26,6 +26,12 @@ test('normalizeVariable key ordering', () => {
26
26
  });
27
27
 
28
28
  test('saveConfig and loadConfig roundtrip', () => {
29
+ // Save the current config to restore later
30
+ let savedConfig: PtConfig | null = null;
31
+ if (fs.existsSync(CONFIG_PATH)) {
32
+ savedConfig = loadConfig();
33
+ }
34
+
29
35
  // Clean up any existing test files
30
36
  if (fs.existsSync(CONFIG_PATH)) {
31
37
  fs.unlinkSync(CONFIG_PATH);
@@ -92,7 +98,651 @@ test('saveConfig and loadConfig roundtrip', () => {
92
98
  if (fs.existsSync(backupPath)) {
93
99
  fs.unlinkSync(backupPath);
94
100
  }
101
+
102
+ // Restore the original config if it existed
103
+ if (savedConfig) {
104
+ saveConfig(savedConfig);
105
+ }
106
+
107
+ if (fs.existsSync(testHome)) {
108
+ fs.rmdirSync(testHome);
109
+ }
110
+ });
111
+
112
+ test('normalizeVariable with minimal input', () => {
113
+ const variableInput = {
114
+ name: 'minimalVar'
115
+ };
116
+
117
+ const normalized = normalizeVariable(variableInput);
118
+
119
+ // Verify that only name is present
120
+ const keys = Object.keys(normalized);
121
+ assert.deepStrictEqual(keys, ['name']);
122
+ assert.strictEqual(normalized.name, 'minimalVar');
123
+ });
124
+
125
+ test('normalizeVariable with all fields', () => {
126
+ const variableInput = {
127
+ required: false,
128
+ default: 'default-value',
129
+ prompt: 'Custom prompt:',
130
+ name: 'allFields'
131
+ };
132
+
133
+ const normalized = normalizeVariable(variableInput);
134
+
135
+ // Verify all fields are present and in correct order
136
+ const keys = Object.keys(normalized);
137
+ assert.deepStrictEqual(keys, ['name', 'prompt', 'default', 'required']);
138
+ assert.strictEqual(normalized.name, 'allFields');
139
+ assert.strictEqual(normalized.prompt, 'Custom prompt:');
140
+ assert.strictEqual(normalized.default, 'default-value');
141
+ assert.strictEqual(normalized.required, false);
142
+ });
143
+
144
+ test('saveConfig creates backup on overwrite', () => {
145
+ // Save the current config to restore later
146
+ let savedConfig: PtConfig | null = null;
147
+ if (fs.existsSync(CONFIG_PATH)) {
148
+ savedConfig = loadConfig();
149
+ }
150
+
151
+ // Clean up any existing test files
152
+ if (fs.existsSync(CONFIG_PATH)) {
153
+ fs.unlinkSync(CONFIG_PATH);
154
+ }
155
+ const backupPath = CONFIG_PATH + '.bak';
156
+ if (fs.existsSync(backupPath)) {
157
+ fs.unlinkSync(backupPath);
158
+ }
159
+
160
+ const config1: PtConfig = {
161
+ version: '1.0.0',
162
+ templates: {}
163
+ };
164
+ const config2: PtConfig = {
165
+ version: '2.0.0',
166
+ templates: {}
167
+ };
168
+
169
+ // Save first config
170
+ saveConfig(config1);
171
+ assert.ok(fs.existsSync(CONFIG_PATH), 'Config file should be created');
172
+
173
+ // Save second config (should create backup)
174
+ saveConfig(config2);
175
+ assert.ok(fs.existsSync(backupPath), 'Backup file should exist');
176
+
177
+ // Verify backup contains first config
178
+ const backupContent = fs.readFileSync(backupPath, 'utf-8');
179
+ assert.ok(backupContent.includes("version: 1.0.0") || backupContent.includes("version: '1.0.0'"), 'Backup should contain previous version');
180
+
181
+ // Clean up
182
+ if (fs.existsSync(CONFIG_PATH)) {
183
+ fs.unlinkSync(CONFIG_PATH);
184
+ }
185
+ if (fs.existsSync(backupPath)) {
186
+ fs.unlinkSync(backupPath);
187
+ }
188
+
189
+ // Restore the original config if it existed
190
+ if (savedConfig) {
191
+ saveConfig(savedConfig);
192
+ }
193
+
194
+ if (fs.existsSync(testHome)) {
195
+ fs.rmdirSync(testHome);
196
+ }
197
+ });
198
+
199
+ test('saveConfig atomic write behavior', () => {
200
+ // Save the current config to restore later
201
+ let savedConfig: PtConfig | null = null;
202
+ if (fs.existsSync(CONFIG_PATH)) {
203
+ savedConfig = loadConfig();
204
+ }
205
+
206
+ // Clean up any existing test files
207
+ if (fs.existsSync(CONFIG_PATH)) {
208
+ fs.unlinkSync(CONFIG_PATH);
209
+ }
210
+ const backupPath = CONFIG_PATH + '.bak';
211
+ if (fs.existsSync(backupPath)) {
212
+ fs.unlinkSync(backupPath);
213
+ }
214
+
215
+ const config: PtConfig = {
216
+ version: '1.0.0',
217
+ templates: {}
218
+ };
219
+
220
+ // Save config - should use atomic write
221
+ saveConfig(config);
222
+
223
+ // Verify config exists
224
+ assert.ok(fs.existsSync(CONFIG_PATH), 'Config file should be created');
225
+
226
+ // Verify no temp file remains
227
+ const tempPath = CONFIG_PATH + '.tmp';
228
+ assert.ok(!fs.existsSync(tempPath), 'Temp file should not remain');
229
+
230
+ // Clean up
231
+ if (fs.existsSync(CONFIG_PATH)) {
232
+ fs.unlinkSync(CONFIG_PATH);
233
+ }
234
+ if (fs.existsSync(backupPath)) {
235
+ fs.unlinkSync(backupPath);
236
+ }
237
+
238
+ // Restore the original config if it existed
239
+ if (savedConfig) {
240
+ saveConfig(savedConfig);
241
+ }
242
+
243
+ if (fs.existsSync(testHome)) {
244
+ fs.rmdirSync(testHome);
245
+ }
246
+ });
247
+
248
+ test('loadConfig returns default config when file missing', () => {
249
+ // Save the current config to restore later
250
+ let savedConfig: PtConfig | null = null;
251
+ if (fs.existsSync(CONFIG_PATH)) {
252
+ savedConfig = loadConfig();
253
+ }
254
+
255
+ // Clean up any existing test files
256
+ if (fs.existsSync(CONFIG_PATH)) {
257
+ fs.unlinkSync(CONFIG_PATH);
258
+ }
259
+ const backupPath = CONFIG_PATH + '.bak';
260
+ if (fs.existsSync(backupPath)) {
261
+ fs.unlinkSync(backupPath);
262
+ }
263
+
264
+ const config = loadConfig();
265
+
266
+ // Verify default config structure
267
+ assert.strictEqual(config.version, '3.0');
268
+ assert.deepStrictEqual(config.templates, {});
269
+ assert.deepStrictEqual(config.default_post_config, []);
270
+ assert.deepStrictEqual(config.variables, []);
271
+
272
+ // Clean up
273
+ if (fs.existsSync(testHome)) {
274
+ fs.rmdirSync(testHome);
275
+ }
276
+
277
+ // Restore the original config if it existed
278
+ if (savedConfig) {
279
+ saveConfig(savedConfig);
280
+ }
281
+ });
282
+
283
+ test('saveConfig with variables normalizes key order', () => {
284
+ // Save the current config to restore later
285
+ let savedConfig: PtConfig | null = null;
286
+ if (fs.existsSync(CONFIG_PATH)) {
287
+ savedConfig = loadConfig();
288
+ }
289
+
290
+ // Clean up any existing test files
291
+ if (fs.existsSync(CONFIG_PATH)) {
292
+ fs.unlinkSync(CONFIG_PATH);
293
+ }
294
+ const backupPath = CONFIG_PATH + '.bak';
295
+ if (fs.existsSync(backupPath)) {
296
+ fs.unlinkSync(backupPath);
297
+ }
298
+
299
+ const config: PtConfig = {
300
+ version: '1.0.0',
301
+ templates: {
302
+ 'test-template': {
303
+ description: 'Test',
304
+ folders: [],
305
+ variables: [
306
+ {
307
+ required: true,
308
+ default: 'value1',
309
+ prompt: 'Prompt1:',
310
+ name: 'var1'
311
+ },
312
+ {
313
+ required: false,
314
+ default: 'value2',
315
+ prompt: 'Prompt2:',
316
+ name: 'var2'
317
+ }
318
+ ]
319
+ }
320
+ }
321
+ };
322
+
323
+ // Save config
324
+ saveConfig(config);
325
+
326
+ // Load and verify
327
+ const loaded = loadConfig();
328
+ const vars = loaded.templates['test-template'].variables;
329
+
330
+ assert.strictEqual(vars.length, 2, 'Should have 2 variables');
331
+ assert.strictEqual(vars[0].name, 'var1', 'First variable name should be var1');
332
+ assert.strictEqual(vars[1].name, 'var2', 'Second variable name should be var2');
333
+
334
+ // Clean up
335
+ if (fs.existsSync(CONFIG_PATH)) {
336
+ fs.unlinkSync(CONFIG_PATH);
337
+ }
338
+ if (fs.existsSync(backupPath)) {
339
+ fs.unlinkSync(backupPath);
340
+ }
341
+
342
+ // Restore the original config if it existed
343
+ if (savedConfig) {
344
+ saveConfig(savedConfig);
345
+ }
346
+
347
+ if (fs.existsSync(testHome)) {
348
+ fs.rmdirSync(testHome);
349
+ }
350
+ });
351
+
352
+ test('saveConfig with empty config file', () => {
353
+ // Save the current config to restore later
354
+ let savedConfig: PtConfig | null = null;
355
+ if (fs.existsSync(CONFIG_PATH)) {
356
+ savedConfig = loadConfig();
357
+ }
358
+
359
+ // Clean up any existing test files
360
+ if (fs.existsSync(CONFIG_PATH)) {
361
+ fs.unlinkSync(CONFIG_PATH);
362
+ }
363
+ const backupPath = CONFIG_PATH + '.bak';
364
+ if (fs.existsSync(backupPath)) {
365
+ fs.unlinkSync(backupPath);
366
+ }
367
+
368
+ // Create empty config file
369
+ fs.writeFileSync(CONFIG_PATH, '');
370
+
371
+ // Try to load - should throw error
372
+ assert.throws(() => {
373
+ loadConfig();
374
+ }, /Config file is empty/, 'Should throw error for empty config file');
375
+
376
+ // Clean up
377
+ if (fs.existsSync(CONFIG_PATH)) {
378
+ fs.unlinkSync(CONFIG_PATH);
379
+ }
380
+ if (fs.existsSync(backupPath)) {
381
+ fs.unlinkSync(backupPath);
382
+ }
383
+
384
+ // Restore the original config if it existed
385
+ if (savedConfig) {
386
+ saveConfig(savedConfig);
387
+ }
388
+
389
+ if (fs.existsSync(testHome)) {
390
+ fs.rmdirSync(testHome);
391
+ }
392
+ });
393
+
394
+ test('normalizeVariable preserves field order', () => {
395
+ const variableInput = {
396
+ required: true,
397
+ default: 'my-default',
398
+ prompt: 'Enter variable:',
399
+ name: 'varName'
400
+ };
401
+
402
+ const normalized = normalizeVariable(variableInput);
403
+
404
+ // Verify field order is preserved
405
+ const keys = Object.keys(normalized);
406
+ assert.deepStrictEqual(keys, ['name', 'prompt', 'default', 'required']);
407
+ });
408
+
409
+ test('saveConfig handles multiple templates', () => {
410
+ // Save the current config to restore later
411
+ let savedConfig: PtConfig | null = null;
412
+ if (fs.existsSync(CONFIG_PATH)) {
413
+ savedConfig = loadConfig();
414
+ }
415
+
416
+ // Clean up any existing test files
417
+ if (fs.existsSync(CONFIG_PATH)) {
418
+ fs.unlinkSync(CONFIG_PATH);
419
+ }
420
+ const backupPath = CONFIG_PATH + '.bak';
421
+ if (fs.existsSync(backupPath)) {
422
+ fs.unlinkSync(backupPath);
423
+ }
424
+
425
+ const config: PtConfig = {
426
+ version: '1.0.0',
427
+ templates: {
428
+ 'template1': {
429
+ description: 'Template 1',
430
+ folders: []
431
+ },
432
+ 'template2': {
433
+ description: 'Template 2',
434
+ folders: []
435
+ }
436
+ }
437
+ };
438
+
439
+ // Save config
440
+ saveConfig(config);
441
+
442
+ // Load and verify
443
+ const loaded = loadConfig();
444
+ assert.strictEqual(Object.keys(loaded.templates).length, 2, 'Should have 2 templates');
445
+ assert.strictEqual(loaded.templates['template1'].description, 'Template 1');
446
+ assert.strictEqual(loaded.templates['template2'].description, 'Template 2');
447
+
448
+ // Clean up
449
+ if (fs.existsSync(CONFIG_PATH)) {
450
+ fs.unlinkSync(CONFIG_PATH);
451
+ }
452
+ if (fs.existsSync(backupPath)) {
453
+ fs.unlinkSync(backupPath);
454
+ }
455
+
456
+ // Restore the original config if it existed
457
+ if (savedConfig) {
458
+ saveConfig(savedConfig);
459
+ }
460
+
461
+ if (fs.existsSync(testHome)) {
462
+ fs.rmdirSync(testHome);
463
+ }
464
+ });
465
+
466
+ test('saveConfig handles templates with variables', () => {
467
+ // Save the current config to restore later
468
+ let savedConfig: PtConfig | null = null;
469
+ if (fs.existsSync(CONFIG_PATH)) {
470
+ savedConfig = loadConfig();
471
+ }
472
+
473
+ // Clean up any existing test files
474
+ if (fs.existsSync(CONFIG_PATH)) {
475
+ fs.unlinkSync(CONFIG_PATH);
476
+ }
477
+ const backupPath = CONFIG_PATH + '.bak';
478
+ if (fs.existsSync(backupPath)) {
479
+ fs.unlinkSync(backupPath);
480
+ }
481
+
482
+ const config: PtConfig = {
483
+ version: '1.0.0',
484
+ templates: {
485
+ 'template-with-vars': {
486
+ description: 'Template with variables',
487
+ folders: [],
488
+ variables: [
489
+ {
490
+ required: true,
491
+ default: 'default-value',
492
+ prompt: 'Enter value:',
493
+ name: 'myVar'
494
+ }
495
+ ]
496
+ }
497
+ }
498
+ };
499
+
500
+ // Save config
501
+ saveConfig(config);
502
+
503
+ // Load and verify
504
+ const loaded = loadConfig();
505
+ const template = loaded.templates['template-with-vars'];
506
+
507
+ assert.ok(template, 'Template should exist');
508
+ assert.strictEqual(template.variables?.length, 1, 'Should have 1 variable');
509
+ assert.strictEqual(template.variables?.[0].name, 'myVar', 'Variable name should be myVar');
510
+ assert.strictEqual(template.variables?.[0].prompt, 'Enter value:', 'Variable prompt should match');
511
+ assert.strictEqual(template.variables?.[0].default, 'default-value', 'Variable default should match');
512
+ assert.strictEqual(template.variables?.[0].required, true, 'Variable should be required');
513
+
514
+ // Clean up
515
+ if (fs.existsSync(CONFIG_PATH)) {
516
+ fs.unlinkSync(CONFIG_PATH);
517
+ }
518
+ if (fs.existsSync(backupPath)) {
519
+ fs.unlinkSync(backupPath);
520
+ }
521
+
522
+ // Restore the original config if it existed
523
+ if (savedConfig) {
524
+ saveConfig(savedConfig);
525
+ }
526
+
527
+ if (fs.existsSync(testHome)) {
528
+ fs.rmdirSync(testHome);
529
+ }
530
+ });
531
+
532
+ test('loadConfig handles migration from v2.0', () => {
533
+ // Save the current config to restore later
534
+ let savedConfig: PtConfig | null = null;
535
+ if (fs.existsSync(CONFIG_PATH)) {
536
+ savedConfig = loadConfig();
537
+ }
538
+
539
+ // Clean up any existing test files
540
+ if (fs.existsSync(CONFIG_PATH)) {
541
+ fs.unlinkSync(CONFIG_PATH);
542
+ }
543
+ const backupPath = CONFIG_PATH + '.bak';
544
+ if (fs.existsSync(backupPath)) {
545
+ fs.unlinkSync(backupPath);
546
+ }
547
+
548
+ // Create a v2.0 config
549
+ const v2Config = {
550
+ version: '2.0',
551
+ templates: {
552
+ 'test-template': {
553
+ name: 'Test Template',
554
+ description: 'Test Description',
555
+ type: 'web',
556
+ folders: []
557
+ }
558
+ }
559
+ };
560
+
561
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(v2Config));
562
+
563
+ // Load config - should migrate to v3.0
564
+ const config = loadConfig();
565
+
566
+ // Verify migration happened
567
+ assert.strictEqual(config.version, '3.0', 'Should be migrated to v3.0');
568
+ assert.strictEqual(config.templates['test-template'].description, 'Test Template', 'Name should be migrated to description');
569
+ assert.ok(!config.templates['test-template'].type, 'Type should be removed');
570
+
571
+ // Clean up
572
+ if (fs.existsSync(CONFIG_PATH)) {
573
+ fs.unlinkSync(CONFIG_PATH);
574
+ }
575
+ if (fs.existsSync(backupPath)) {
576
+ fs.unlinkSync(backupPath);
577
+ }
578
+
579
+ // Restore the original config if it existed
580
+ if (savedConfig) {
581
+ saveConfig(savedConfig);
582
+ }
583
+
584
+ if (fs.existsSync(testHome)) {
585
+ fs.rmdirSync(testHome);
586
+ }
587
+ });
588
+
589
+ test('loadConfig handles migration from v2.0 with global_post_config', () => {
590
+ // Save the current config to restore later
591
+ let savedConfig: PtConfig | null = null;
592
+ if (fs.existsSync(CONFIG_PATH)) {
593
+ savedConfig = loadConfig();
594
+ }
595
+
596
+ // Clean up any existing test files
597
+ if (fs.existsSync(CONFIG_PATH)) {
598
+ fs.unlinkSync(CONFIG_PATH);
599
+ }
600
+ const backupPath = CONFIG_PATH + '.bak';
601
+ if (fs.existsSync(backupPath)) {
602
+ fs.unlinkSync(backupPath);
603
+ }
604
+
605
+ // Create a v2.0 config with global_post_config
606
+ const v2Config = {
607
+ version: '2.0',
608
+ templates: {},
609
+ global_post_config: [
610
+ {
611
+ command: 'npm install',
612
+ description: 'Install dependencies'
613
+ }
614
+ ]
615
+ };
616
+
617
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(v2Config));
618
+
619
+ // Load config - should migrate to v3.0
620
+ const config = loadConfig();
621
+
622
+ // Verify migration happened
623
+ assert.strictEqual(config.version, '3.0', 'Should be migrated to v3.0');
624
+ assert.deepStrictEqual(config.default_post_config, [
625
+ {
626
+ command: 'npm install',
627
+ description: 'Install dependencies'
628
+ }
629
+ ], 'global_post_config should be migrated to default_post_config');
630
+ assert.ok(!config.global_post_config, 'global_post_config should be removed');
631
+
632
+ // Clean up
633
+ if (fs.existsSync(CONFIG_PATH)) {
634
+ fs.unlinkSync(CONFIG_PATH);
635
+ }
636
+ if (fs.existsSync(backupPath)) {
637
+ fs.unlinkSync(backupPath);
638
+ }
639
+
640
+ // Restore the original config if it existed
641
+ if (savedConfig) {
642
+ saveConfig(savedConfig);
643
+ }
644
+
645
+ if (fs.existsSync(testHome)) {
646
+ fs.rmdirSync(testHome);
647
+ }
648
+ });
649
+
650
+ test('loadConfig handles migration from v2.0 with variables', () => {
651
+ // Save the current config to restore later
652
+ let savedConfig: PtConfig | null = null;
653
+ if (fs.existsSync(CONFIG_PATH)) {
654
+ savedConfig = loadConfig();
655
+ }
656
+
657
+ // Clean up any existing test files
658
+ if (fs.existsSync(CONFIG_PATH)) {
659
+ fs.unlinkSync(CONFIG_PATH);
660
+ }
661
+ const backupPath = CONFIG_PATH + '.bak';
662
+ if (fs.existsSync(backupPath)) {
663
+ fs.unlinkSync(backupPath);
664
+ }
665
+
666
+ // Create a v2.0 config with variables as Record<string, string>
667
+ const v2Config = {
668
+ version: '2.0',
669
+ templates: {},
670
+ variables: {
671
+ 'client_name': 'My Client',
672
+ 'project_type': 'web'
673
+ }
674
+ };
675
+
676
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(v2Config));
677
+
678
+ // Load config - should migrate to v3.0
679
+ const config = loadConfig();
680
+
681
+ // Verify migration happened
682
+ assert.strictEqual(config.version, '3.0', 'Should be migrated to v3.0');
683
+ assert.strictEqual(config.variables.length, 2, 'Should have 2 variables');
684
+ assert.strictEqual(config.variables[0].name, 'client_name', 'First variable name should be client_name');
685
+ assert.strictEqual(config.variables[0].default, 'My Client', 'First variable default should be My Client');
686
+ assert.strictEqual(config.variables[1].name, 'project_type', 'Second variable name should be project_type');
687
+ assert.strictEqual(config.variables[1].default, 'web', 'Second variable default should be web');
688
+
689
+ // Clean up
690
+ if (fs.existsSync(CONFIG_PATH)) {
691
+ fs.unlinkSync(CONFIG_PATH);
692
+ }
693
+ if (fs.existsSync(backupPath)) {
694
+ fs.unlinkSync(backupPath);
695
+ }
696
+
697
+ // Restore the original config if it existed
698
+ if (savedConfig) {
699
+ saveConfig(savedConfig);
700
+ }
701
+
95
702
  if (fs.existsSync(testHome)) {
96
703
  fs.rmdirSync(testHome);
97
704
  }
98
705
  });
706
+
707
+ test('loadConfig handles existing config file', () => {
708
+ // Don't delete the existing config file - let it be restored by the user
709
+ // This test verifies that loadConfig works with an existing config
710
+ const config = loadConfig();
711
+
712
+ // Verify config is loaded correctly
713
+ assert.ok(config, 'Config should be loaded');
714
+ assert.ok(config.templates, 'Templates should exist');
715
+ assert.ok(config.version, 'Version should exist');
716
+ });
717
+
718
+ test('saveConfig preserves existing config when not deleting', () => {
719
+ // Save the current config to restore later
720
+ let savedConfig: PtConfig | null = null;
721
+ if (fs.existsSync(CONFIG_PATH)) {
722
+ savedConfig = loadConfig();
723
+ }
724
+
725
+ // Don't delete the config file - test saving without deletion
726
+ const config: PtConfig = {
727
+ version: '1.0.0',
728
+ templates: {
729
+ 'test-template': {
730
+ description: 'Test',
731
+ folders: []
732
+ }
733
+ }
734
+ };
735
+
736
+ // Save config
737
+ saveConfig(config);
738
+
739
+ // Load and verify
740
+ const loaded = loadConfig();
741
+ assert.strictEqual(loaded.version, '1.0.0');
742
+ assert.ok(loaded.templates['test-template']);
743
+
744
+ // Restore the original config if it existed
745
+ if (savedConfig) {
746
+ saveConfig(savedConfig);
747
+ }
748
+ });