pict-section-inlinedocumentation 0.0.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.
Files changed (51) hide show
  1. package/README.md +107 -0
  2. package/docs/.nojekyll +0 -0
  3. package/docs/README.md +83 -0
  4. package/docs/_cover.md +15 -0
  5. package/docs/_sidebar.md +24 -0
  6. package/docs/_topbar.md +8 -0
  7. package/docs/_version.json +7 -0
  8. package/docs/api-reference.md +185 -0
  9. package/docs/architecture.md +103 -0
  10. package/docs/css/docuserve.css +327 -0
  11. package/docs/embedding-level1-sidebar.md +92 -0
  12. package/docs/embedding-level2-routes.md +86 -0
  13. package/docs/embedding-level3-tooltips.md +97 -0
  14. package/docs/embedding-level4-autogen.md +126 -0
  15. package/docs/index.html +39 -0
  16. package/docs/overview.md +42 -0
  17. package/docs/quickstart.md +95 -0
  18. package/docs/reference.md +73 -0
  19. package/docs/retold-catalog.json +181 -0
  20. package/docs/retold-keyword-index.json +4374 -0
  21. package/example_applications/basic/docs/README.md +40 -0
  22. package/example_applications/basic/docs/_sidebar.md +4 -0
  23. package/example_applications/basic/docs/_topics.json +10 -0
  24. package/example_applications/basic/docs/advanced-topics.md +47 -0
  25. package/example_applications/basic/docs/getting-started.md +70 -0
  26. package/example_applications/basic/index.html +100 -0
  27. package/example_applications/bookshop/.quackage.json +10 -0
  28. package/example_applications/bookshop/Pict-Application-Bookshop-Configuration.json +15 -0
  29. package/example_applications/bookshop/Pict-Application-Bookshop.js +218 -0
  30. package/example_applications/bookshop/data/BookshopData.json +65 -0
  31. package/example_applications/bookshop/data/pict_documentation_topics.json +46 -0
  32. package/example_applications/bookshop/docs/_sidebar.md +6 -0
  33. package/example_applications/bookshop/docs/book-detail.md +21 -0
  34. package/example_applications/bookshop/docs/book-list.md +21 -0
  35. package/example_applications/bookshop/docs/search-filter.md +18 -0
  36. package/example_applications/bookshop/docs/store.md +29 -0
  37. package/example_applications/bookshop/docs/welcome.md +23 -0
  38. package/example_applications/bookshop/html/index.html +236 -0
  39. package/example_applications/bookshop/package.json +34 -0
  40. package/example_applications/bookshop/views/PictView-Bookshop-BookList.js +324 -0
  41. package/example_applications/bookshop/views/PictView-Bookshop-HelpToggle.js +44 -0
  42. package/example_applications/bookshop/views/PictView-Bookshop-Store.js +271 -0
  43. package/package.json +55 -0
  44. package/source/Pict-Section-InlineDocumentation.js +10 -0
  45. package/source/providers/Pict-Provider-InlineDocumentation.js +1995 -0
  46. package/source/views/Pict-View-InlineDocumentation-Content.js +542 -0
  47. package/source/views/Pict-View-InlineDocumentation-Layout.js +206 -0
  48. package/source/views/Pict-View-InlineDocumentation-Nav.js +475 -0
  49. package/source/views/Pict-View-InlineDocumentation-TopicManager.js +1623 -0
  50. package/test/Browser_Integration_tests.js +1449 -0
  51. package/test/Pict-Section-InlineDocumentation_test.js +1285 -0
@@ -0,0 +1,1285 @@
1
+ const libPict = require('pict');
2
+ const libInlineDocumentation = require('../source/Pict-Section-InlineDocumentation.js');
3
+
4
+ const libAssert = require('assert');
5
+
6
+ suite
7
+ (
8
+ 'Pict-Section-InlineDocumentation',
9
+ () =>
10
+ {
11
+ setup(() => { });
12
+
13
+ suite
14
+ (
15
+ 'Module Exports',
16
+ () =>
17
+ {
18
+ test
19
+ (
20
+ 'Module should export the provider as the default export',
21
+ (fDone) =>
22
+ {
23
+ libAssert.strictEqual(typeof libInlineDocumentation, 'function', 'Default export should be a constructor');
24
+ libAssert.ok(libInlineDocumentation.default_configuration, 'Should export default_configuration');
25
+ libAssert.strictEqual(libInlineDocumentation.default_configuration.ProviderIdentifier, 'Pict-InlineDocumentation');
26
+ return fDone();
27
+ }
28
+ );
29
+ test
30
+ (
31
+ 'Module should export view classes',
32
+ (fDone) =>
33
+ {
34
+ libAssert.strictEqual(typeof libInlineDocumentation.InlineDocumentationLayoutView, 'function', 'Should export layout view');
35
+ libAssert.strictEqual(typeof libInlineDocumentation.InlineDocumentationContentView, 'function', 'Should export content view');
36
+ libAssert.strictEqual(typeof libInlineDocumentation.InlineDocumentationNavView, 'function', 'Should export nav view');
37
+ return fDone();
38
+ }
39
+ );
40
+ }
41
+ );
42
+
43
+ suite
44
+ (
45
+ 'Provider Registration',
46
+ () =>
47
+ {
48
+ test
49
+ (
50
+ 'Provider should register with Pict and instantiate views',
51
+ (fDone) =>
52
+ {
53
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
54
+
55
+ let tmpProvider = tmpPict.addProvider(
56
+ 'Pict-InlineDocumentation',
57
+ libInlineDocumentation.default_configuration,
58
+ libInlineDocumentation);
59
+
60
+ libAssert.ok(tmpProvider, 'Provider should be created');
61
+ libAssert.ok(tmpPict.providers['Pict-InlineDocumentation'], 'Provider should be registered');
62
+
63
+ // Views should be registered
64
+ libAssert.ok(tmpPict.views['InlineDoc-Layout'], 'Layout view should be registered');
65
+ libAssert.ok(tmpPict.views['InlineDoc-Content'], 'Content view should be registered');
66
+ libAssert.ok(tmpPict.views['InlineDoc-Nav'], 'Nav view should be registered');
67
+
68
+ // Content provider should be registered
69
+ libAssert.ok(tmpPict.providers['Pict-Content'], 'Content provider should be registered');
70
+
71
+ return fDone();
72
+ }
73
+ );
74
+
75
+ test
76
+ (
77
+ 'Provider should have expected API methods',
78
+ (fDone) =>
79
+ {
80
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
81
+
82
+ let tmpProvider = tmpPict.addProvider(
83
+ 'Pict-InlineDocumentation',
84
+ libInlineDocumentation.default_configuration,
85
+ libInlineDocumentation);
86
+
87
+ libAssert.strictEqual(typeof tmpProvider.initializeDocumentation, 'function', 'Should have initializeDocumentation');
88
+ libAssert.strictEqual(typeof tmpProvider.loadDocument, 'function', 'Should have loadDocument');
89
+ libAssert.strictEqual(typeof tmpProvider.setTopic, 'function', 'Should have setTopic');
90
+ libAssert.strictEqual(typeof tmpProvider.clearTopic, 'function', 'Should have clearTopic');
91
+ libAssert.strictEqual(typeof tmpProvider.setDocsBaseURL, 'function', 'Should have setDocsBaseURL');
92
+ libAssert.strictEqual(typeof tmpProvider.getNavigationHistory, 'function', 'Should have getNavigationHistory');
93
+ libAssert.strictEqual(typeof tmpProvider.navigateBack, 'function', 'Should have navigateBack');
94
+
95
+ return fDone();
96
+ }
97
+ );
98
+ }
99
+ );
100
+
101
+ suite
102
+ (
103
+ 'State Management',
104
+ () =>
105
+ {
106
+ test
107
+ (
108
+ 'setDocsBaseURL should update state and clear cache',
109
+ (fDone) =>
110
+ {
111
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
112
+
113
+ let tmpProvider = tmpPict.addProvider(
114
+ 'Pict-InlineDocumentation',
115
+ libInlineDocumentation.default_configuration,
116
+ libInlineDocumentation);
117
+
118
+ tmpProvider.setDocsBaseURL('https://example.com/docs/');
119
+
120
+ libAssert.strictEqual(
121
+ tmpPict.AppData.InlineDocumentation.DocsBaseURL,
122
+ 'https://example.com/docs/');
123
+
124
+ return fDone();
125
+ }
126
+ );
127
+
128
+ test
129
+ (
130
+ 'getNavigationHistory should return empty array initially',
131
+ (fDone) =>
132
+ {
133
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
134
+
135
+ let tmpProvider = tmpPict.addProvider(
136
+ 'Pict-InlineDocumentation',
137
+ libInlineDocumentation.default_configuration,
138
+ libInlineDocumentation);
139
+
140
+ let tmpHistory = tmpProvider.getNavigationHistory();
141
+ libAssert.ok(Array.isArray(tmpHistory), 'Should return an array');
142
+ libAssert.strictEqual(tmpHistory.length, 0, 'Should be empty initially');
143
+
144
+ return fDone();
145
+ }
146
+ );
147
+ }
148
+ );
149
+
150
+ suite
151
+ (
152
+ 'Sidebar Parsing',
153
+ () =>
154
+ {
155
+ test
156
+ (
157
+ 'Should parse _sidebar.md format into groups and items',
158
+ (fDone) =>
159
+ {
160
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
161
+
162
+ let tmpProvider = tmpPict.addProvider(
163
+ 'Pict-InlineDocumentation',
164
+ libInlineDocumentation.default_configuration,
165
+ libInlineDocumentation);
166
+
167
+ let tmpSidebar = '- [Home](README.md)\n'
168
+ + '- Guide\n'
169
+ + ' - [Getting Started](getting-started.md)\n'
170
+ + ' - [Advanced](advanced-topics.md)\n';
171
+
172
+ let tmpGroups = tmpProvider._parseSidebarMarkdown(tmpSidebar);
173
+
174
+ libAssert.strictEqual(tmpGroups.length, 2, 'Should have 2 groups');
175
+
176
+ // First group: Home (link)
177
+ libAssert.strictEqual(tmpGroups[0].Name, 'Home');
178
+ libAssert.strictEqual(tmpGroups[0].Path, 'README.md');
179
+ libAssert.strictEqual(tmpGroups[0].Items.length, 0);
180
+
181
+ // Second group: Guide (plain text header with children)
182
+ libAssert.strictEqual(tmpGroups[1].Name, 'Guide');
183
+ libAssert.strictEqual(tmpGroups[1].Path, '');
184
+ libAssert.strictEqual(tmpGroups[1].Items.length, 2);
185
+ libAssert.strictEqual(tmpGroups[1].Items[0].Name, 'Getting Started');
186
+ libAssert.strictEqual(tmpGroups[1].Items[0].Path, 'getting-started.md');
187
+ libAssert.strictEqual(tmpGroups[1].Items[1].Name, 'Advanced');
188
+ libAssert.strictEqual(tmpGroups[1].Items[1].Path, 'advanced-topics.md');
189
+
190
+ return fDone();
191
+ }
192
+ );
193
+
194
+ test
195
+ (
196
+ 'Should handle leading slashes and ./ in paths',
197
+ (fDone) =>
198
+ {
199
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
200
+
201
+ let tmpProvider = tmpPict.addProvider(
202
+ 'Pict-InlineDocumentation',
203
+ libInlineDocumentation.default_configuration,
204
+ libInlineDocumentation);
205
+
206
+ let tmpSidebar = '- [Page One](/page-one.md)\n'
207
+ + '- [Page Two](./page-two.md)\n';
208
+
209
+ let tmpGroups = tmpProvider._parseSidebarMarkdown(tmpSidebar);
210
+
211
+ libAssert.strictEqual(tmpGroups.length, 2);
212
+ libAssert.strictEqual(tmpGroups[0].Path, 'page-one.md');
213
+ libAssert.strictEqual(tmpGroups[1].Path, 'page-two.md');
214
+
215
+ return fDone();
216
+ }
217
+ );
218
+ }
219
+ );
220
+
221
+ suite
222
+ (
223
+ 'Link Resolution',
224
+ () =>
225
+ {
226
+ test
227
+ (
228
+ 'Should resolve external links with target blank',
229
+ (fDone) =>
230
+ {
231
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
232
+
233
+ let tmpProvider = tmpPict.addProvider(
234
+ 'Pict-InlineDocumentation',
235
+ libInlineDocumentation.default_configuration,
236
+ libInlineDocumentation);
237
+
238
+ let tmpResolver = tmpProvider._createLinkResolver();
239
+ let tmpResult = tmpResolver('https://example.com', 'Example');
240
+
241
+ libAssert.strictEqual(tmpResult.href, 'https://example.com');
242
+ libAssert.strictEqual(tmpResult.target, '_blank');
243
+ libAssert.strictEqual(tmpResult.rel, 'noopener');
244
+
245
+ return fDone();
246
+ }
247
+ );
248
+
249
+ test
250
+ (
251
+ 'Should resolve internal links with doc path data',
252
+ (fDone) =>
253
+ {
254
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
255
+
256
+ let tmpProvider = tmpPict.addProvider(
257
+ 'Pict-InlineDocumentation',
258
+ libInlineDocumentation.default_configuration,
259
+ libInlineDocumentation);
260
+
261
+ let tmpResolver = tmpProvider._createLinkResolver();
262
+ let tmpResult = tmpResolver('getting-started.md', 'Getting Started');
263
+
264
+ libAssert.strictEqual(tmpResult.href, 'javascript:void(0)');
265
+ libAssert.ok(tmpResult.rel.indexOf('pict-inline-doc-link:getting-started.md') >= 0);
266
+
267
+ return fDone();
268
+ }
269
+ );
270
+ }
271
+ );
272
+
273
+ suite
274
+ (
275
+ 'Image Resolution',
276
+ () =>
277
+ {
278
+ test
279
+ (
280
+ 'Should resolve relative images against doc URL',
281
+ (fDone) =>
282
+ {
283
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
284
+
285
+ let tmpProvider = tmpPict.addProvider(
286
+ 'Pict-InlineDocumentation',
287
+ libInlineDocumentation.default_configuration,
288
+ libInlineDocumentation);
289
+
290
+ let tmpResolver = tmpProvider._createImageResolver('https://example.com/docs/guide/page.md');
291
+
292
+ let tmpResult = tmpResolver('diagram.png', 'Diagram');
293
+ libAssert.strictEqual(tmpResult, 'https://example.com/docs/guide/diagram.png');
294
+
295
+ return fDone();
296
+ }
297
+ );
298
+
299
+ test
300
+ (
301
+ 'Should leave absolute image URLs unchanged',
302
+ (fDone) =>
303
+ {
304
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
305
+
306
+ let tmpProvider = tmpPict.addProvider(
307
+ 'Pict-InlineDocumentation',
308
+ libInlineDocumentation.default_configuration,
309
+ libInlineDocumentation);
310
+
311
+ let tmpResolver = tmpProvider._createImageResolver('https://example.com/docs/page.md');
312
+
313
+ let tmpAbsolute = tmpResolver('https://cdn.example.com/image.png', 'Image');
314
+ libAssert.strictEqual(tmpAbsolute, 'https://cdn.example.com/image.png');
315
+
316
+ let tmpData = tmpResolver('data:image/png;base64,abc', 'Data');
317
+ libAssert.strictEqual(tmpData, 'data:image/png;base64,abc');
318
+
319
+ return fDone();
320
+ }
321
+ );
322
+ }
323
+ );
324
+
325
+ suite
326
+ (
327
+ 'Error Handling',
328
+ () =>
329
+ {
330
+ test
331
+ (
332
+ 'loadDocument should callback with error for empty path',
333
+ (fDone) =>
334
+ {
335
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
336
+
337
+ let tmpProvider = tmpPict.addProvider(
338
+ 'Pict-InlineDocumentation',
339
+ libInlineDocumentation.default_configuration,
340
+ libInlineDocumentation);
341
+
342
+ tmpProvider.loadDocument('', (pError) =>
343
+ {
344
+ libAssert.ok(pError, 'Should return an error');
345
+ return fDone();
346
+ });
347
+ }
348
+ );
349
+
350
+ test
351
+ (
352
+ 'setTopic should warn for unknown topic',
353
+ (fDone) =>
354
+ {
355
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
356
+
357
+ let tmpProvider = tmpPict.addProvider(
358
+ 'Pict-InlineDocumentation',
359
+ libInlineDocumentation.default_configuration,
360
+ libInlineDocumentation);
361
+
362
+ tmpProvider.setDocsBaseURL('/docs/');
363
+
364
+ // Should not throw
365
+ tmpProvider.setTopic('nonexistent-topic');
366
+
367
+ return fDone();
368
+ }
369
+ );
370
+ }
371
+ );
372
+
373
+ suite
374
+ (
375
+ 'Route Matching',
376
+ () =>
377
+ {
378
+ test
379
+ (
380
+ 'Should match exact routes',
381
+ (fDone) =>
382
+ {
383
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
384
+
385
+ let tmpProvider = tmpPict.addProvider(
386
+ 'Pict-InlineDocumentation',
387
+ libInlineDocumentation.default_configuration,
388
+ libInlineDocumentation);
389
+
390
+ tmpProvider.setDocsBaseURL('/docs/');
391
+ tmpPict.AppData.InlineDocumentation.Topics = {
392
+ 'TOPIC-A': { TopicCode: 'TOPIC-A', Routes: ['/books'] },
393
+ 'TOPIC-B': { TopicCode: 'TOPIC-B', Routes: ['/settings'] }
394
+ };
395
+
396
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/books'), 'TOPIC-A');
397
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/settings'), 'TOPIC-B');
398
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/unknown'), null);
399
+
400
+ return fDone();
401
+ }
402
+ );
403
+
404
+ test
405
+ (
406
+ 'Should match wildcard routes',
407
+ (fDone) =>
408
+ {
409
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
410
+
411
+ let tmpProvider = tmpPict.addProvider(
412
+ 'Pict-InlineDocumentation',
413
+ libInlineDocumentation.default_configuration,
414
+ libInlineDocumentation);
415
+
416
+ tmpProvider.setDocsBaseURL('/docs/');
417
+ tmpPict.AppData.InlineDocumentation.Topics = {
418
+ 'STORE': { TopicCode: 'STORE', Routes: ['/books/store/*'] }
419
+ };
420
+
421
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/books/store/123'), 'STORE');
422
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/books/store/123/details'), 'STORE');
423
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/books/store'), 'STORE');
424
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/books'), null);
425
+
426
+ return fDone();
427
+ }
428
+ );
429
+
430
+ test
431
+ (
432
+ 'Should prefer longest matching pattern',
433
+ (fDone) =>
434
+ {
435
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
436
+
437
+ let tmpProvider = tmpPict.addProvider(
438
+ 'Pict-InlineDocumentation',
439
+ libInlineDocumentation.default_configuration,
440
+ libInlineDocumentation);
441
+
442
+ tmpProvider.setDocsBaseURL('/docs/');
443
+ tmpPict.AppData.InlineDocumentation.Topics = {
444
+ 'BOOKS': { TopicCode: 'BOOKS', Routes: ['/books/*'] },
445
+ 'STORE': { TopicCode: 'STORE', Routes: ['/books/store/*'] }
446
+ };
447
+
448
+ // /books/store/5 matches both, but STORE has longer prefix
449
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/books/store/5'), 'STORE');
450
+ // /books/catalog matches only BOOKS
451
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/books/catalog'), 'BOOKS');
452
+
453
+ return fDone();
454
+ }
455
+ );
456
+
457
+ test
458
+ (
459
+ 'Should handle topics without Routes array',
460
+ (fDone) =>
461
+ {
462
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
463
+
464
+ let tmpProvider = tmpPict.addProvider(
465
+ 'Pict-InlineDocumentation',
466
+ libInlineDocumentation.default_configuration,
467
+ libInlineDocumentation);
468
+
469
+ tmpProvider.setDocsBaseURL('/docs/');
470
+ tmpPict.AppData.InlineDocumentation.Topics = {
471
+ 'NO-ROUTES': { TopicCode: 'NO-ROUTES', TopicHelpFilePath: 'test.md' },
472
+ 'HAS-ROUTES': { TopicCode: 'HAS-ROUTES', Routes: ['/test'] }
473
+ };
474
+
475
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/test'), 'HAS-ROUTES');
476
+ libAssert.strictEqual(tmpProvider.resolveHelpForRoute('/other'), null);
477
+
478
+ return fDone();
479
+ }
480
+ );
481
+
482
+ test
483
+ (
484
+ 'navigateToRoute should return true for matched routes',
485
+ (fDone) =>
486
+ {
487
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
488
+
489
+ let tmpProvider = tmpPict.addProvider(
490
+ 'Pict-InlineDocumentation',
491
+ libInlineDocumentation.default_configuration,
492
+ libInlineDocumentation);
493
+
494
+ tmpProvider.setDocsBaseURL('/docs/');
495
+ tmpPict.AppData.InlineDocumentation.NavigationHistory = [];
496
+ tmpPict.AppData.InlineDocumentation.CurrentPath = '';
497
+ tmpPict.AppData.InlineDocumentation.Topics = {
498
+ 'FOUND': { TopicCode: 'FOUND', TopicHelpFilePath: 'found.md', Routes: ['/found'] }
499
+ };
500
+
501
+ // navigateToRoute calls loadTopicDocument which calls loadDocument
502
+ // which will fail to fetch, but that's fine — we're testing the return value
503
+ libAssert.strictEqual(tmpProvider.navigateToRoute('/found'), true);
504
+ libAssert.strictEqual(tmpProvider.navigateToRoute('/not-found'), false);
505
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.CurrentRoute, '/not-found');
506
+
507
+ return fDone();
508
+ }
509
+ );
510
+ }
511
+ );
512
+
513
+ suite
514
+ (
515
+ 'Edit Mode',
516
+ () =>
517
+ {
518
+ test
519
+ (
520
+ 'setEditEnabled should update state',
521
+ (fDone) =>
522
+ {
523
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
524
+
525
+ let tmpProvider = tmpPict.addProvider(
526
+ 'Pict-InlineDocumentation',
527
+ libInlineDocumentation.default_configuration,
528
+ libInlineDocumentation);
529
+
530
+ tmpProvider.setDocsBaseURL('/docs/');
531
+ // EditEnabled is only initialized by initializeDocumentation,
532
+ // but setEditEnabled creates it if missing
533
+ tmpProvider.setEditEnabled(false);
534
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.EditEnabled, false);
535
+
536
+ tmpProvider.setEditEnabled(true);
537
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.EditEnabled, true);
538
+
539
+ tmpProvider.setEditEnabled(false);
540
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.EditEnabled, false);
541
+
542
+ return fDone();
543
+ }
544
+ );
545
+
546
+ test
547
+ (
548
+ 'Provider should have edit API methods',
549
+ (fDone) =>
550
+ {
551
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
552
+
553
+ let tmpProvider = tmpPict.addProvider(
554
+ 'Pict-InlineDocumentation',
555
+ libInlineDocumentation.default_configuration,
556
+ libInlineDocumentation);
557
+
558
+ libAssert.strictEqual(typeof tmpProvider.setEditEnabled, 'function');
559
+ libAssert.strictEqual(typeof tmpProvider.toggleEdit, 'function');
560
+ libAssert.strictEqual(typeof tmpProvider.beginEdit, 'function');
561
+ libAssert.strictEqual(typeof tmpProvider.cancelEdit, 'function');
562
+ libAssert.strictEqual(typeof tmpProvider.saveEdit, 'function');
563
+
564
+ return fDone();
565
+ }
566
+ );
567
+
568
+ test
569
+ (
570
+ 'Provider should have route API methods',
571
+ (fDone) =>
572
+ {
573
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
574
+
575
+ let tmpProvider = tmpPict.addProvider(
576
+ 'Pict-InlineDocumentation',
577
+ libInlineDocumentation.default_configuration,
578
+ libInlineDocumentation);
579
+
580
+ libAssert.strictEqual(typeof tmpProvider.resolveHelpForRoute, 'function');
581
+ libAssert.strictEqual(typeof tmpProvider.navigateToRoute, 'function');
582
+
583
+ return fDone();
584
+ }
585
+ );
586
+
587
+ test
588
+ (
589
+ 'Cache should store both html and markdown',
590
+ (fDone) =>
591
+ {
592
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
593
+
594
+ let tmpProvider = tmpPict.addProvider(
595
+ 'Pict-InlineDocumentation',
596
+ libInlineDocumentation.default_configuration,
597
+ libInlineDocumentation);
598
+
599
+ // Manually populate cache to test format
600
+ tmpProvider._ContentCache['test.md'] = { html: '<p>test</p>', markdown: '# test' };
601
+
602
+ let tmpEntry = tmpProvider._ContentCache['test.md'];
603
+ libAssert.ok(tmpEntry.html, 'Cache entry should have html');
604
+ libAssert.ok(tmpEntry.markdown, 'Cache entry should have markdown');
605
+ libAssert.strictEqual(tmpEntry.html, '<p>test</p>');
606
+ libAssert.strictEqual(tmpEntry.markdown, '# test');
607
+
608
+ return fDone();
609
+ }
610
+ );
611
+ }
612
+ );
613
+
614
+ suite
615
+ (
616
+ 'Topic CRUD',
617
+ () =>
618
+ {
619
+ test
620
+ (
621
+ 'getTopicList should return array of topic summaries',
622
+ (fDone) =>
623
+ {
624
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
625
+
626
+ let tmpProvider = tmpPict.addProvider(
627
+ 'Pict-InlineDocumentation',
628
+ libInlineDocumentation.default_configuration,
629
+ libInlineDocumentation);
630
+
631
+ tmpProvider.setDocsBaseURL('/docs/');
632
+ tmpPict.AppData.InlineDocumentation.Topics = {
633
+ 'TOPIC-A': { TopicCode: 'TOPIC-A', TopicTitle: 'Topic Alpha', TopicHelpFilePath: 'alpha.md', Routes: ['/alpha', '/alpha/*'] },
634
+ 'TOPIC-B': { TopicCode: 'TOPIC-B', TopicTitle: 'Topic Beta', TopicHelpFilePath: 'beta.md', Routes: [] }
635
+ };
636
+
637
+ let tmpList = tmpProvider.getTopicList();
638
+
639
+ libAssert.ok(Array.isArray(tmpList), 'Should return an array');
640
+ libAssert.strictEqual(tmpList.length, 2, 'Should have 2 topics');
641
+ libAssert.strictEqual(tmpList[0].TopicCode, 'TOPIC-A');
642
+ libAssert.strictEqual(tmpList[0].TopicTitle, 'Topic Alpha');
643
+ libAssert.strictEqual(tmpList[0].TopicHelpFilePath, 'alpha.md');
644
+ libAssert.strictEqual(tmpList[0].RouteCount, 2);
645
+ libAssert.strictEqual(tmpList[1].RouteCount, 0);
646
+
647
+ return fDone();
648
+ }
649
+ );
650
+
651
+ test
652
+ (
653
+ 'getTopicList should return empty array when no topics',
654
+ (fDone) =>
655
+ {
656
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
657
+
658
+ let tmpProvider = tmpPict.addProvider(
659
+ 'Pict-InlineDocumentation',
660
+ libInlineDocumentation.default_configuration,
661
+ libInlineDocumentation);
662
+
663
+ let tmpList = tmpProvider.getTopicList();
664
+ libAssert.ok(Array.isArray(tmpList));
665
+ libAssert.strictEqual(tmpList.length, 0);
666
+
667
+ return fDone();
668
+ }
669
+ );
670
+
671
+ test
672
+ (
673
+ 'updateTopic should merge only specified fields',
674
+ (fDone) =>
675
+ {
676
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
677
+
678
+ let tmpProvider = tmpPict.addProvider(
679
+ 'Pict-InlineDocumentation',
680
+ libInlineDocumentation.default_configuration,
681
+ libInlineDocumentation);
682
+
683
+ tmpProvider.setDocsBaseURL('/docs/');
684
+ tmpPict.AppData.InlineDocumentation.Topics = {
685
+ 'MY-TOPIC': { TopicCode: 'MY-TOPIC', TopicTitle: 'Original', TopicHelpFilePath: 'orig.md', Routes: ['/orig'] }
686
+ };
687
+
688
+ let tmpResult = tmpProvider.updateTopic('MY-TOPIC', { TopicTitle: 'Updated Title' });
689
+
690
+ libAssert.strictEqual(tmpResult, true);
691
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.Topics['MY-TOPIC'].TopicTitle, 'Updated Title');
692
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.Topics['MY-TOPIC'].TopicHelpFilePath, 'orig.md');
693
+ libAssert.deepStrictEqual(tmpPict.AppData.InlineDocumentation.Topics['MY-TOPIC'].Routes, ['/orig']);
694
+
695
+ return fDone();
696
+ }
697
+ );
698
+
699
+ test
700
+ (
701
+ 'updateTopic should return false for nonexistent topic',
702
+ (fDone) =>
703
+ {
704
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
705
+
706
+ let tmpProvider = tmpPict.addProvider(
707
+ 'Pict-InlineDocumentation',
708
+ libInlineDocumentation.default_configuration,
709
+ libInlineDocumentation);
710
+
711
+ tmpProvider.setDocsBaseURL('/docs/');
712
+ tmpPict.AppData.InlineDocumentation.Topics = {};
713
+
714
+ libAssert.strictEqual(tmpProvider.updateTopic('NOPE', { TopicTitle: 'Test' }), false);
715
+
716
+ return fDone();
717
+ }
718
+ );
719
+
720
+ test
721
+ (
722
+ 'removeTopic should delete topic and clear active if matched',
723
+ (fDone) =>
724
+ {
725
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
726
+
727
+ let tmpProvider = tmpPict.addProvider(
728
+ 'Pict-InlineDocumentation',
729
+ libInlineDocumentation.default_configuration,
730
+ libInlineDocumentation);
731
+
732
+ tmpProvider.setDocsBaseURL('/docs/');
733
+ tmpPict.AppData.InlineDocumentation.Topics = {
734
+ 'REMOVE-ME': { TopicCode: 'REMOVE-ME', TopicTitle: 'Doomed' }
735
+ };
736
+ tmpPict.AppData.InlineDocumentation.Topic = 'REMOVE-ME';
737
+
738
+ let tmpResult = tmpProvider.removeTopic('REMOVE-ME');
739
+
740
+ libAssert.strictEqual(tmpResult, true);
741
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.Topics['REMOVE-ME'], undefined);
742
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.Topic, null);
743
+
744
+ return fDone();
745
+ }
746
+ );
747
+
748
+ test
749
+ (
750
+ 'removeTopic should return false for nonexistent topic',
751
+ (fDone) =>
752
+ {
753
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
754
+
755
+ let tmpProvider = tmpPict.addProvider(
756
+ 'Pict-InlineDocumentation',
757
+ libInlineDocumentation.default_configuration,
758
+ libInlineDocumentation);
759
+
760
+ tmpProvider.setDocsBaseURL('/docs/');
761
+ tmpPict.AppData.InlineDocumentation.Topics = {};
762
+
763
+ libAssert.strictEqual(tmpProvider.removeTopic('NOPE'), false);
764
+
765
+ return fDone();
766
+ }
767
+ );
768
+
769
+ test
770
+ (
771
+ 'removeRouteFromTopic should splice route from array',
772
+ (fDone) =>
773
+ {
774
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
775
+
776
+ let tmpProvider = tmpPict.addProvider(
777
+ 'Pict-InlineDocumentation',
778
+ libInlineDocumentation.default_configuration,
779
+ libInlineDocumentation);
780
+
781
+ tmpProvider.setDocsBaseURL('/docs/');
782
+ tmpPict.AppData.InlineDocumentation.Topics = {
783
+ 'TOPIC-X': { TopicCode: 'TOPIC-X', Routes: ['/one', '/two', '/three'] }
784
+ };
785
+
786
+ libAssert.strictEqual(tmpProvider.removeRouteFromTopic('TOPIC-X', '/two'), true);
787
+ libAssert.deepStrictEqual(tmpPict.AppData.InlineDocumentation.Topics['TOPIC-X'].Routes, ['/one', '/three']);
788
+ libAssert.strictEqual(tmpProvider.removeRouteFromTopic('TOPIC-X', '/two'), false);
789
+
790
+ return fDone();
791
+ }
792
+ );
793
+
794
+ test
795
+ (
796
+ 'saveTopics should call onTopicsSave callback',
797
+ (fDone) =>
798
+ {
799
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
800
+
801
+ let tmpProvider = tmpPict.addProvider(
802
+ 'Pict-InlineDocumentation',
803
+ libInlineDocumentation.default_configuration,
804
+ libInlineDocumentation);
805
+
806
+ tmpProvider.setDocsBaseURL('/docs/');
807
+ tmpPict.AppData.InlineDocumentation.Topics = {
808
+ 'TEST': { TopicCode: 'TEST', TopicTitle: 'Test' }
809
+ };
810
+
811
+ let tmpSavedTopics = null;
812
+ tmpProvider._onTopicsSave = (pTopics, fCallback) =>
813
+ {
814
+ tmpSavedTopics = pTopics;
815
+ fCallback(null);
816
+ };
817
+
818
+ tmpProvider.saveTopics((pError) =>
819
+ {
820
+ libAssert.strictEqual(pError, null);
821
+ libAssert.ok(tmpSavedTopics);
822
+ libAssert.ok(tmpSavedTopics['TEST']);
823
+ return fDone();
824
+ });
825
+ }
826
+ );
827
+
828
+ test
829
+ (
830
+ 'saveTopics should succeed without callback handler',
831
+ (fDone) =>
832
+ {
833
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
834
+
835
+ let tmpProvider = tmpPict.addProvider(
836
+ 'Pict-InlineDocumentation',
837
+ libInlineDocumentation.default_configuration,
838
+ libInlineDocumentation);
839
+
840
+ tmpProvider.setDocsBaseURL('/docs/');
841
+ tmpPict.AppData.InlineDocumentation.Topics = {};
842
+
843
+ tmpProvider.saveTopics((pError) =>
844
+ {
845
+ libAssert.strictEqual(pError, null);
846
+ return fDone();
847
+ });
848
+ }
849
+ );
850
+
851
+ test
852
+ (
853
+ 'setTopicManagerEnabled should update state',
854
+ (fDone) =>
855
+ {
856
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
857
+
858
+ let tmpProvider = tmpPict.addProvider(
859
+ 'Pict-InlineDocumentation',
860
+ libInlineDocumentation.default_configuration,
861
+ libInlineDocumentation);
862
+
863
+ tmpProvider.setDocsBaseURL('/docs/');
864
+
865
+ tmpProvider.setTopicManagerEnabled(true);
866
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.TopicManagerEnabled, true);
867
+
868
+ tmpProvider.setTopicManagerEnabled(false);
869
+ libAssert.strictEqual(tmpPict.AppData.InlineDocumentation.TopicManagerEnabled, false);
870
+
871
+ return fDone();
872
+ }
873
+ );
874
+
875
+ test
876
+ (
877
+ 'Provider should have topic CRUD API methods',
878
+ (fDone) =>
879
+ {
880
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
881
+
882
+ let tmpProvider = tmpPict.addProvider(
883
+ 'Pict-InlineDocumentation',
884
+ libInlineDocumentation.default_configuration,
885
+ libInlineDocumentation);
886
+
887
+ libAssert.strictEqual(typeof tmpProvider.getTopicList, 'function');
888
+ libAssert.strictEqual(typeof tmpProvider.updateTopic, 'function');
889
+ libAssert.strictEqual(typeof tmpProvider.removeTopic, 'function');
890
+ libAssert.strictEqual(typeof tmpProvider.removeRouteFromTopic, 'function');
891
+ libAssert.strictEqual(typeof tmpProvider.saveTopics, 'function');
892
+ libAssert.strictEqual(typeof tmpProvider.setTopicManagerEnabled, 'function');
893
+
894
+ return fDone();
895
+ }
896
+ );
897
+
898
+ test
899
+ (
900
+ 'TopicManager view should be registered',
901
+ (fDone) =>
902
+ {
903
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
904
+
905
+ tmpPict.addProvider(
906
+ 'Pict-InlineDocumentation',
907
+ libInlineDocumentation.default_configuration,
908
+ libInlineDocumentation);
909
+
910
+ libAssert.ok(tmpPict.views['InlineDoc-TopicManager'], 'TopicManager view should be registered');
911
+
912
+ return fDone();
913
+ }
914
+ );
915
+
916
+ test
917
+ (
918
+ 'Module should export TopicManager view class',
919
+ (fDone) =>
920
+ {
921
+ libAssert.strictEqual(typeof libInlineDocumentation.InlineDocumentationTopicManagerView, 'function');
922
+ return fDone();
923
+ }
924
+ );
925
+ }
926
+ );
927
+
928
+ suite
929
+ (
930
+ 'Wildcard Builder Helpers',
931
+ () =>
932
+ {
933
+ test
934
+ (
935
+ 'getRouteSegments should split route into segments',
936
+ (fDone) =>
937
+ {
938
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
939
+
940
+ let tmpProvider = tmpPict.addProvider(
941
+ 'Pict-InlineDocumentation',
942
+ libInlineDocumentation.default_configuration,
943
+ libInlineDocumentation);
944
+
945
+ let tmpSegments = tmpProvider.getRouteSegments('/books/detail/5');
946
+
947
+ libAssert.strictEqual(tmpSegments.length, 3);
948
+
949
+ libAssert.strictEqual(tmpSegments[0].Segment, 'books');
950
+ libAssert.strictEqual(tmpSegments[0].Path, '/books');
951
+ libAssert.strictEqual(tmpSegments[0].WildcardPattern, '/books/*');
952
+ libAssert.strictEqual(tmpSegments[0].Index, 0);
953
+
954
+ libAssert.strictEqual(tmpSegments[1].Segment, 'detail');
955
+ libAssert.strictEqual(tmpSegments[1].Path, '/books/detail');
956
+ libAssert.strictEqual(tmpSegments[1].WildcardPattern, '/books/detail/*');
957
+ libAssert.strictEqual(tmpSegments[1].Index, 1);
958
+
959
+ libAssert.strictEqual(tmpSegments[2].Segment, '5');
960
+ libAssert.strictEqual(tmpSegments[2].Path, '/books/detail/5');
961
+ libAssert.strictEqual(tmpSegments[2].WildcardPattern, '/books/detail/5/*');
962
+ libAssert.strictEqual(tmpSegments[2].Index, 2);
963
+
964
+ return fDone();
965
+ }
966
+ );
967
+
968
+ test
969
+ (
970
+ 'getRouteSegments should return empty array for empty/invalid input',
971
+ (fDone) =>
972
+ {
973
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
974
+
975
+ let tmpProvider = tmpPict.addProvider(
976
+ 'Pict-InlineDocumentation',
977
+ libInlineDocumentation.default_configuration,
978
+ libInlineDocumentation);
979
+
980
+ libAssert.deepStrictEqual(tmpProvider.getRouteSegments(''), []);
981
+ libAssert.deepStrictEqual(tmpProvider.getRouteSegments(null), []);
982
+ libAssert.deepStrictEqual(tmpProvider.getRouteSegments(undefined), []);
983
+ libAssert.deepStrictEqual(tmpProvider.getRouteSegments('/'), []);
984
+
985
+ return fDone();
986
+ }
987
+ );
988
+
989
+ test
990
+ (
991
+ 'buildWildcardPattern should create correct patterns',
992
+ (fDone) =>
993
+ {
994
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
995
+
996
+ let tmpProvider = tmpPict.addProvider(
997
+ 'Pict-InlineDocumentation',
998
+ libInlineDocumentation.default_configuration,
999
+ libInlineDocumentation);
1000
+
1001
+ libAssert.strictEqual(tmpProvider.buildWildcardPattern('/books/detail/5', 0), '/books/*');
1002
+ libAssert.strictEqual(tmpProvider.buildWildcardPattern('/books/detail/5', 1), '/books/detail/*');
1003
+ libAssert.strictEqual(tmpProvider.buildWildcardPattern('/books/detail/5', 2), '/books/detail/5/*');
1004
+
1005
+ return fDone();
1006
+ }
1007
+ );
1008
+
1009
+ test
1010
+ (
1011
+ 'buildWildcardPattern should return empty string for invalid input',
1012
+ (fDone) =>
1013
+ {
1014
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1015
+
1016
+ let tmpProvider = tmpPict.addProvider(
1017
+ 'Pict-InlineDocumentation',
1018
+ libInlineDocumentation.default_configuration,
1019
+ libInlineDocumentation);
1020
+
1021
+ libAssert.strictEqual(tmpProvider.buildWildcardPattern('', 0), '');
1022
+ libAssert.strictEqual(tmpProvider.buildWildcardPattern('/books', -1), '');
1023
+ libAssert.strictEqual(tmpProvider.buildWildcardPattern('/books', 5), '');
1024
+
1025
+ return fDone();
1026
+ }
1027
+ );
1028
+
1029
+ test
1030
+ (
1031
+ 'getTopicsForRoute should return all matching topics sorted by match length',
1032
+ (fDone) =>
1033
+ {
1034
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1035
+
1036
+ let tmpProvider = tmpPict.addProvider(
1037
+ 'Pict-InlineDocumentation',
1038
+ libInlineDocumentation.default_configuration,
1039
+ libInlineDocumentation);
1040
+
1041
+ tmpProvider.setDocsBaseURL('/docs/');
1042
+ tmpPict.AppData.InlineDocumentation.Topics = {
1043
+ 'BOOKS': { TopicCode: 'BOOKS', Routes: ['/books/*'] },
1044
+ 'STORE': { TopicCode: 'STORE', Routes: ['/books/store/*'] },
1045
+ 'SETTINGS': { TopicCode: 'SETTINGS', Routes: ['/settings'] }
1046
+ };
1047
+
1048
+ let tmpMatches = tmpProvider.getTopicsForRoute('/books/store/5');
1049
+
1050
+ libAssert.strictEqual(tmpMatches.length, 2);
1051
+ libAssert.strictEqual(tmpMatches[0].TopicCode, 'STORE');
1052
+ libAssert.strictEqual(tmpMatches[1].TopicCode, 'BOOKS');
1053
+
1054
+ return fDone();
1055
+ }
1056
+ );
1057
+ }
1058
+ );
1059
+
1060
+ suite
1061
+ (
1062
+ 'Tooltip Content',
1063
+ () =>
1064
+ {
1065
+ test
1066
+ (
1067
+ 'getTooltipContent should return content from active topic',
1068
+ (fDone) =>
1069
+ {
1070
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1071
+
1072
+ let tmpProvider = tmpPict.addProvider(
1073
+ 'Pict-InlineDocumentation',
1074
+ libInlineDocumentation.default_configuration,
1075
+ libInlineDocumentation);
1076
+
1077
+ tmpProvider.setDocsBaseURL('/docs/');
1078
+ tmpPict.AppData.InlineDocumentation.Topics = {
1079
+ 'HELP-TOPIC': {
1080
+ TopicCode: 'HELP-TOPIC',
1081
+ TopicTitle: 'Help',
1082
+ Tooltips: {
1083
+ 'field_name': { Content: '**Bold** help text' },
1084
+ 'empty_tip': { Content: '' }
1085
+ }
1086
+ }
1087
+ };
1088
+ tmpPict.AppData.InlineDocumentation.Topic = 'HELP-TOPIC';
1089
+
1090
+ libAssert.strictEqual(tmpProvider.getTooltipContent('field_name'), '**Bold** help text');
1091
+ libAssert.strictEqual(tmpProvider.getTooltipContent('empty_tip'), null);
1092
+ libAssert.strictEqual(tmpProvider.getTooltipContent('nonexistent'), null);
1093
+
1094
+ return fDone();
1095
+ }
1096
+ );
1097
+
1098
+ test
1099
+ (
1100
+ 'getTooltipContent should return null when no active topic',
1101
+ (fDone) =>
1102
+ {
1103
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1104
+
1105
+ let tmpProvider = tmpPict.addProvider(
1106
+ 'Pict-InlineDocumentation',
1107
+ libInlineDocumentation.default_configuration,
1108
+ libInlineDocumentation);
1109
+
1110
+ tmpProvider.setDocsBaseURL('/docs/');
1111
+ tmpPict.AppData.InlineDocumentation.Topics = {
1112
+ 'HELP-TOPIC': {
1113
+ TopicCode: 'HELP-TOPIC',
1114
+ Tooltips: { 'tip': { Content: 'Some content' } }
1115
+ }
1116
+ };
1117
+ tmpPict.AppData.InlineDocumentation.Topic = null;
1118
+
1119
+ libAssert.strictEqual(tmpProvider.getTooltipContent('tip'), null);
1120
+
1121
+ return fDone();
1122
+ }
1123
+ );
1124
+
1125
+ test
1126
+ (
1127
+ 'getTooltipContent should return null when topic has no Tooltips',
1128
+ (fDone) =>
1129
+ {
1130
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1131
+
1132
+ let tmpProvider = tmpPict.addProvider(
1133
+ 'Pict-InlineDocumentation',
1134
+ libInlineDocumentation.default_configuration,
1135
+ libInlineDocumentation);
1136
+
1137
+ tmpProvider.setDocsBaseURL('/docs/');
1138
+ tmpPict.AppData.InlineDocumentation.Topics = {
1139
+ 'NO-TIPS': { TopicCode: 'NO-TIPS', TopicTitle: 'No Tips' }
1140
+ };
1141
+ tmpPict.AppData.InlineDocumentation.Topic = 'NO-TIPS';
1142
+
1143
+ libAssert.strictEqual(tmpProvider.getTooltipContent('anything'), null);
1144
+
1145
+ return fDone();
1146
+ }
1147
+ );
1148
+
1149
+ test
1150
+ (
1151
+ 'setTooltipContent should create Tooltips hash lazily',
1152
+ (fDone) =>
1153
+ {
1154
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1155
+
1156
+ let tmpProvider = tmpPict.addProvider(
1157
+ 'Pict-InlineDocumentation',
1158
+ libInlineDocumentation.default_configuration,
1159
+ libInlineDocumentation);
1160
+
1161
+ tmpProvider.setDocsBaseURL('/docs/');
1162
+ tmpPict.AppData.InlineDocumentation.Topics = {
1163
+ 'MY-TOPIC': { TopicCode: 'MY-TOPIC', TopicTitle: 'Test' }
1164
+ };
1165
+ tmpPict.AppData.InlineDocumentation.Topic = 'MY-TOPIC';
1166
+
1167
+ let tmpResult = tmpProvider.setTooltipContent('new_tip', 'Hello world');
1168
+
1169
+ libAssert.strictEqual(tmpResult, true);
1170
+ libAssert.ok(tmpPict.AppData.InlineDocumentation.Topics['MY-TOPIC'].Tooltips);
1171
+ libAssert.strictEqual(
1172
+ tmpPict.AppData.InlineDocumentation.Topics['MY-TOPIC'].Tooltips['new_tip'].Content,
1173
+ 'Hello world');
1174
+
1175
+ return fDone();
1176
+ }
1177
+ );
1178
+
1179
+ test
1180
+ (
1181
+ 'setTooltipContent should remove entry when content is null',
1182
+ (fDone) =>
1183
+ {
1184
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1185
+
1186
+ let tmpProvider = tmpPict.addProvider(
1187
+ 'Pict-InlineDocumentation',
1188
+ libInlineDocumentation.default_configuration,
1189
+ libInlineDocumentation);
1190
+
1191
+ tmpProvider.setDocsBaseURL('/docs/');
1192
+ tmpPict.AppData.InlineDocumentation.Topics = {
1193
+ 'MY-TOPIC': {
1194
+ TopicCode: 'MY-TOPIC',
1195
+ Tooltips: { 'old_tip': { Content: 'Remove me' } }
1196
+ }
1197
+ };
1198
+ tmpPict.AppData.InlineDocumentation.Topic = 'MY-TOPIC';
1199
+
1200
+ libAssert.strictEqual(tmpProvider.setTooltipContent('old_tip', null), true);
1201
+ libAssert.strictEqual(
1202
+ tmpPict.AppData.InlineDocumentation.Topics['MY-TOPIC'].Tooltips['old_tip'],
1203
+ undefined);
1204
+
1205
+ return fDone();
1206
+ }
1207
+ );
1208
+
1209
+ test
1210
+ (
1211
+ 'setTooltipContent should return false when no active topic',
1212
+ (fDone) =>
1213
+ {
1214
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1215
+
1216
+ let tmpProvider = tmpPict.addProvider(
1217
+ 'Pict-InlineDocumentation',
1218
+ libInlineDocumentation.default_configuration,
1219
+ libInlineDocumentation);
1220
+
1221
+ tmpProvider.setDocsBaseURL('/docs/');
1222
+ tmpPict.AppData.InlineDocumentation.Topics = {};
1223
+ tmpPict.AppData.InlineDocumentation.Topic = null;
1224
+
1225
+ libAssert.strictEqual(tmpProvider.setTooltipContent('tip', 'content'), false);
1226
+
1227
+ return fDone();
1228
+ }
1229
+ );
1230
+
1231
+ test
1232
+ (
1233
+ 'clearTooltipBindings should empty the bindings array',
1234
+ (fDone) =>
1235
+ {
1236
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1237
+
1238
+ let tmpProvider = tmpPict.addProvider(
1239
+ 'Pict-InlineDocumentation',
1240
+ libInlineDocumentation.default_configuration,
1241
+ libInlineDocumentation);
1242
+
1243
+ tmpProvider._ActiveTooltipBindings.push(
1244
+ {
1245
+ Element: null,
1246
+ Key: 'test',
1247
+ Type: 'attribute',
1248
+ TooltipHandle: null,
1249
+ ClickHandler: null,
1250
+ InjectedIcon: null,
1251
+ OriginalDisplay: undefined
1252
+ });
1253
+
1254
+ libAssert.strictEqual(tmpProvider._ActiveTooltipBindings.length, 1);
1255
+ tmpProvider.clearTooltipBindings();
1256
+ libAssert.strictEqual(tmpProvider._ActiveTooltipBindings.length, 0);
1257
+
1258
+ return fDone();
1259
+ }
1260
+ );
1261
+
1262
+ test
1263
+ (
1264
+ 'Provider should have tooltip API methods',
1265
+ (fDone) =>
1266
+ {
1267
+ let tmpPict = new libPict({ Product: 'InlineDocTest' });
1268
+
1269
+ let tmpProvider = tmpPict.addProvider(
1270
+ 'Pict-InlineDocumentation',
1271
+ libInlineDocumentation.default_configuration,
1272
+ libInlineDocumentation);
1273
+
1274
+ libAssert.strictEqual(typeof tmpProvider.getTooltipContent, 'function');
1275
+ libAssert.strictEqual(typeof tmpProvider.setTooltipContent, 'function');
1276
+ libAssert.strictEqual(typeof tmpProvider.clearTooltipBindings, 'function');
1277
+ libAssert.strictEqual(typeof tmpProvider.scanTooltips, 'function');
1278
+
1279
+ return fDone();
1280
+ }
1281
+ );
1282
+ }
1283
+ );
1284
+ }
1285
+ );