@bendyline/squisq 0.1.2 → 1.1.0
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/dist/{themeLibrary-DySHPcgj.d.ts → Doc-1hmT1LZl.d.ts} +1 -42
- package/dist/MediaProvider-wpSe21B3.d.ts +66 -0
- package/dist/__tests__/animationUtils.test.d.ts +2 -0
- package/dist/__tests__/animationUtils.test.d.ts.map +1 -0
- package/dist/__tests__/animationUtils.test.js +60 -0
- package/dist/__tests__/animationUtils.test.js.map +1 -0
- package/dist/__tests__/contentContainer.test.d.ts +2 -0
- package/dist/__tests__/contentContainer.test.d.ts.map +1 -0
- package/dist/__tests__/contentContainer.test.js +234 -0
- package/dist/__tests__/contentContainer.test.js.map +1 -0
- package/dist/__tests__/contentExtractor.test.d.ts +2 -0
- package/dist/__tests__/contentExtractor.test.d.ts.map +1 -0
- package/dist/__tests__/contentExtractor.test.js +151 -0
- package/dist/__tests__/contentExtractor.test.js.map +1 -0
- package/dist/__tests__/geohash.test.d.ts +2 -0
- package/dist/__tests__/geohash.test.d.ts.map +1 -0
- package/dist/__tests__/geohash.test.js +87 -0
- package/dist/__tests__/geohash.test.js.map +1 -0
- package/dist/__tests__/getLayers.test.d.ts +2 -0
- package/dist/__tests__/getLayers.test.d.ts.map +1 -0
- package/dist/__tests__/getLayers.test.js +167 -0
- package/dist/__tests__/getLayers.test.js.map +1 -0
- package/dist/__tests__/haversine.test.d.ts +2 -0
- package/dist/__tests__/haversine.test.d.ts.map +1 -0
- package/dist/__tests__/haversine.test.js +56 -0
- package/dist/__tests__/haversine.test.js.map +1 -0
- package/dist/__tests__/localForageAdapter.test.d.ts +8 -0
- package/dist/__tests__/localForageAdapter.test.d.ts.map +1 -0
- package/dist/__tests__/localForageAdapter.test.js +130 -0
- package/dist/__tests__/localForageAdapter.test.js.map +1 -0
- package/dist/__tests__/markdown.test.d.ts +2 -0
- package/dist/__tests__/markdown.test.d.ts.map +1 -0
- package/dist/__tests__/markdown.test.js +654 -0
- package/dist/__tests__/markdown.test.js.map +1 -0
- package/dist/__tests__/markdownToDoc.test.d.ts +2 -0
- package/dist/__tests__/markdownToDoc.test.d.ts.map +1 -0
- package/dist/__tests__/markdownToDoc.test.js +313 -0
- package/dist/__tests__/markdownToDoc.test.js.map +1 -0
- package/dist/__tests__/seededRandom.test.d.ts +2 -0
- package/dist/__tests__/seededRandom.test.d.ts.map +1 -0
- package/dist/__tests__/seededRandom.test.js +125 -0
- package/dist/__tests__/seededRandom.test.js.map +1 -0
- package/dist/__tests__/slideshowGenerator.test.d.ts +2 -0
- package/dist/__tests__/slideshowGenerator.test.d.ts.map +1 -0
- package/dist/__tests__/slideshowGenerator.test.js +114 -0
- package/dist/__tests__/slideshowGenerator.test.js.map +1 -0
- package/dist/__tests__/storage.test.d.ts +2 -0
- package/dist/__tests__/storage.test.d.ts.map +1 -0
- package/dist/__tests__/storage.test.js +51 -0
- package/dist/__tests__/storage.test.js.map +1 -0
- package/dist/__tests__/templates.test.d.ts +2 -0
- package/dist/__tests__/templates.test.d.ts.map +1 -0
- package/dist/__tests__/templates.test.js +217 -0
- package/dist/__tests__/templates.test.js.map +1 -0
- package/dist/__tests__/timing.test.d.ts +2 -0
- package/dist/__tests__/timing.test.d.ts.map +1 -0
- package/dist/__tests__/timing.test.js +131 -0
- package/dist/__tests__/timing.test.js.map +1 -0
- package/dist/chunk-3E5F2XMR.js +129 -0
- package/dist/chunk-3E5F2XMR.js.map +1 -0
- package/dist/chunk-4CRBS35L.js +292 -0
- package/dist/chunk-4CRBS35L.js.map +1 -0
- package/dist/chunk-6YJPI6VI.js +35 -0
- package/dist/chunk-6YJPI6VI.js.map +1 -0
- package/dist/chunk-FVTQSNR7.js +100 -0
- package/dist/chunk-FVTQSNR7.js.map +1 -0
- package/dist/chunk-V543AI2F.js +1 -0
- package/dist/chunk-V543AI2F.js.map +1 -0
- package/dist/chunk-VP5SZTZ2.js +792 -0
- package/dist/chunk-VP5SZTZ2.js.map +1 -0
- package/dist/doc/docToMarkdown.d.ts +41 -0
- package/dist/doc/docToMarkdown.d.ts.map +1 -0
- package/dist/doc/docToMarkdown.js +88 -0
- package/dist/doc/docToMarkdown.js.map +1 -0
- package/dist/doc/getLayers.d.ts +65 -0
- package/dist/doc/getLayers.d.ts.map +1 -0
- package/dist/doc/getLayers.js +103 -0
- package/dist/doc/getLayers.js.map +1 -0
- package/dist/doc/index.d.ts +9 -3
- package/dist/doc/index.d.ts.map +1 -0
- package/dist/doc/index.js +6 -125
- package/dist/doc/index.js.map +1 -1
- package/dist/doc/markdownToDoc.d.ts +68 -0
- package/dist/doc/markdownToDoc.d.ts.map +1 -0
- package/dist/doc/markdownToDoc.js +225 -0
- package/dist/doc/markdownToDoc.js.map +1 -0
- package/dist/doc/templates/accentImage.d.ts +59 -0
- package/dist/doc/templates/accentImage.d.ts.map +1 -0
- package/dist/doc/templates/accentImage.js +275 -0
- package/dist/doc/templates/accentImage.js.map +1 -0
- package/dist/doc/templates/captionUtils.d.ts +20 -0
- package/dist/doc/templates/captionUtils.d.ts.map +1 -0
- package/dist/doc/templates/captionUtils.js +29 -0
- package/dist/doc/templates/captionUtils.js.map +1 -0
- package/dist/doc/templates/comparisonBar.d.ts +13 -0
- package/dist/doc/templates/comparisonBar.d.ts.map +1 -0
- package/dist/doc/templates/comparisonBar.js +127 -0
- package/dist/doc/templates/comparisonBar.js.map +1 -0
- package/dist/doc/templates/coverBlock.d.ts +51 -0
- package/dist/doc/templates/coverBlock.d.ts.map +1 -0
- package/dist/doc/templates/coverBlock.js +125 -0
- package/dist/doc/templates/coverBlock.js.map +1 -0
- package/dist/doc/templates/dateEvent.d.ts +15 -0
- package/dist/doc/templates/dateEvent.d.ts.map +1 -0
- package/dist/doc/templates/dateEvent.js +110 -0
- package/dist/doc/templates/dateEvent.js.map +1 -0
- package/dist/doc/templates/definitionCard.d.ts +13 -0
- package/dist/doc/templates/definitionCard.d.ts.map +1 -0
- package/dist/doc/templates/definitionCard.js +114 -0
- package/dist/doc/templates/definitionCard.js.map +1 -0
- package/dist/doc/templates/factCard.d.ts +15 -0
- package/dist/doc/templates/factCard.d.ts.map +1 -0
- package/dist/doc/templates/factCard.js +100 -0
- package/dist/doc/templates/factCard.js.map +1 -0
- package/dist/doc/templates/fullBleedQuote.d.ts +13 -0
- package/dist/doc/templates/fullBleedQuote.d.ts.map +1 -0
- package/dist/doc/templates/fullBleedQuote.js +54 -0
- package/dist/doc/templates/fullBleedQuote.js.map +1 -0
- package/dist/doc/templates/imageWithCaption.d.ts +13 -0
- package/dist/doc/templates/imageWithCaption.d.ts.map +1 -0
- package/dist/doc/templates/imageWithCaption.js +142 -0
- package/dist/doc/templates/imageWithCaption.js.map +1 -0
- package/dist/doc/templates/index.d.ts +104 -0
- package/dist/doc/templates/index.d.ts.map +1 -0
- package/dist/doc/templates/index.js +442 -0
- package/dist/doc/templates/index.js.map +1 -0
- package/dist/doc/templates/listBlock.d.ts +13 -0
- package/dist/doc/templates/listBlock.d.ts.map +1 -0
- package/dist/doc/templates/listBlock.js +89 -0
- package/dist/doc/templates/listBlock.js.map +1 -0
- package/dist/doc/templates/mapBlock.d.ts +17 -0
- package/dist/doc/templates/mapBlock.d.ts.map +1 -0
- package/dist/doc/templates/mapBlock.js +112 -0
- package/dist/doc/templates/mapBlock.js.map +1 -0
- package/dist/doc/templates/persistentLayers.d.ts +39 -0
- package/dist/doc/templates/persistentLayers.d.ts.map +1 -0
- package/dist/doc/templates/persistentLayers.js +447 -0
- package/dist/doc/templates/persistentLayers.js.map +1 -0
- package/dist/doc/templates/photoGrid.d.ts +20 -0
- package/dist/doc/templates/photoGrid.d.ts.map +1 -0
- package/dist/doc/templates/photoGrid.js +172 -0
- package/dist/doc/templates/photoGrid.js.map +1 -0
- package/dist/doc/templates/pullQuote.d.ts +13 -0
- package/dist/doc/templates/pullQuote.d.ts.map +1 -0
- package/dist/doc/templates/pullQuote.js +109 -0
- package/dist/doc/templates/pullQuote.js.map +1 -0
- package/dist/doc/templates/quoteBlock.d.ts +15 -0
- package/dist/doc/templates/quoteBlock.d.ts.map +1 -0
- package/dist/doc/templates/quoteBlock.js +97 -0
- package/dist/doc/templates/quoteBlock.js.map +1 -0
- package/dist/doc/templates/sectionHeader.d.ts +14 -0
- package/dist/doc/templates/sectionHeader.d.ts.map +1 -0
- package/dist/doc/templates/sectionHeader.js +96 -0
- package/dist/doc/templates/sectionHeader.js.map +1 -0
- package/dist/doc/templates/statHighlight.d.ts +15 -0
- package/dist/doc/templates/statHighlight.d.ts.map +1 -0
- package/dist/doc/templates/statHighlight.js +99 -0
- package/dist/doc/templates/statHighlight.js.map +1 -0
- package/dist/doc/templates/titleBlock.d.ts +13 -0
- package/dist/doc/templates/titleBlock.d.ts.map +1 -0
- package/dist/doc/templates/titleBlock.js +92 -0
- package/dist/doc/templates/titleBlock.js.map +1 -0
- package/dist/doc/templates/twoColumn.d.ts +15 -0
- package/dist/doc/templates/twoColumn.d.ts.map +1 -0
- package/dist/doc/templates/twoColumn.js +219 -0
- package/dist/doc/templates/twoColumn.js.map +1 -0
- package/dist/doc/templates/videoPullQuote.d.ts +20 -0
- package/dist/doc/templates/videoPullQuote.d.ts.map +1 -0
- package/dist/doc/templates/videoPullQuote.js +118 -0
- package/dist/doc/templates/videoPullQuote.js.map +1 -0
- package/dist/doc/templates/videoWithCaption.d.ts +20 -0
- package/dist/doc/templates/videoWithCaption.d.ts.map +1 -0
- package/dist/doc/templates/videoWithCaption.js +104 -0
- package/dist/doc/templates/videoWithCaption.js.map +1 -0
- package/dist/doc/utils/animationUtils.d.ts +34 -0
- package/dist/doc/utils/animationUtils.d.ts.map +1 -0
- package/dist/doc/utils/animationUtils.js +110 -0
- package/dist/doc/utils/animationUtils.js.map +1 -0
- package/dist/doc/utils/themeUtils.d.ts +55 -0
- package/dist/doc/utils/themeUtils.d.ts.map +1 -0
- package/dist/doc/utils/themeUtils.js +109 -0
- package/dist/doc/utils/themeUtils.js.map +1 -0
- package/dist/generate/contentExtractor.d.ts +112 -0
- package/dist/generate/contentExtractor.d.ts.map +1 -0
- package/dist/generate/contentExtractor.js +638 -0
- package/dist/generate/contentExtractor.js.map +1 -0
- package/dist/generate/index.d.ts +7 -0
- package/dist/generate/index.d.ts.map +1 -0
- package/dist/generate/index.js +4 -0
- package/dist/generate/index.js.map +1 -0
- package/dist/generate/slideshowGenerator.d.ts +72 -0
- package/dist/generate/slideshowGenerator.d.ts.map +1 -0
- package/dist/generate/slideshowGenerator.js +159 -0
- package/dist/generate/slideshowGenerator.js.map +1 -0
- package/dist/generate/templateMapper.d.ts +23 -0
- package/dist/generate/templateMapper.d.ts.map +1 -0
- package/dist/generate/templateMapper.js +114 -0
- package/dist/generate/templateMapper.js.map +1 -0
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -216
- package/dist/index.js.map +1 -1
- package/dist/markdown/convert.d.ts +71 -0
- package/dist/markdown/convert.d.ts.map +1 -0
- package/dist/markdown/convert.js +746 -0
- package/dist/markdown/convert.js.map +1 -0
- package/dist/markdown/htmlParse.d.ts +26 -0
- package/dist/markdown/htmlParse.d.ts.map +1 -0
- package/dist/markdown/htmlParse.js +195 -0
- package/dist/markdown/htmlParse.js.map +1 -0
- package/dist/markdown/index.d.ts +19 -225
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +33 -32
- package/dist/markdown/index.js.map +1 -1
- package/dist/markdown/parse.d.ts +27 -0
- package/dist/markdown/parse.d.ts.map +1 -0
- package/dist/markdown/parse.js +90 -0
- package/dist/markdown/parse.js.map +1 -0
- package/dist/markdown/stringify.d.ts +32 -0
- package/dist/markdown/stringify.d.ts.map +1 -0
- package/dist/markdown/stringify.js +108 -0
- package/dist/markdown/stringify.js.map +1 -0
- package/dist/markdown/types.d.ts +496 -0
- package/dist/markdown/types.d.ts.map +1 -0
- package/dist/markdown/types.js +17 -0
- package/dist/markdown/types.js.map +1 -0
- package/dist/markdown/utils.d.ts +78 -0
- package/dist/markdown/utils.d.ts.map +1 -0
- package/dist/markdown/utils.js +149 -0
- package/dist/markdown/utils.js.map +1 -0
- package/dist/random/SeededRandom.d.ts +50 -0
- package/dist/random/SeededRandom.d.ts.map +1 -0
- package/dist/random/SeededRandom.js +115 -0
- package/dist/random/SeededRandom.js.map +1 -0
- package/dist/random/index.d.ts +2 -0
- package/dist/random/index.d.ts.map +1 -0
- package/dist/random/index.js +2 -0
- package/dist/random/index.js.map +1 -0
- package/dist/schemas/BlockTemplates.d.ts +583 -0
- package/dist/schemas/BlockTemplates.d.ts.map +1 -0
- package/dist/schemas/BlockTemplates.js +72 -0
- package/dist/schemas/BlockTemplates.js.map +1 -0
- package/dist/schemas/Doc.d.ts +411 -0
- package/dist/schemas/Doc.d.ts.map +1 -0
- package/dist/schemas/Doc.js +90 -0
- package/dist/schemas/Doc.js.map +1 -0
- package/dist/schemas/LayoutStrategy.d.ts +84 -0
- package/dist/schemas/LayoutStrategy.d.ts.map +1 -0
- package/dist/schemas/LayoutStrategy.js +123 -0
- package/dist/schemas/LayoutStrategy.js.map +1 -0
- package/dist/schemas/MediaProvider.d.ts +65 -0
- package/dist/schemas/MediaProvider.d.ts.map +1 -0
- package/dist/schemas/MediaProvider.js +13 -0
- package/dist/schemas/MediaProvider.js.map +1 -0
- package/dist/schemas/Theme.d.ts +163 -0
- package/dist/schemas/Theme.d.ts.map +1 -0
- package/dist/schemas/Theme.js +62 -0
- package/dist/schemas/Theme.js.map +1 -0
- package/dist/schemas/Types.d.ts +14 -0
- package/dist/schemas/Types.d.ts.map +1 -0
- package/dist/schemas/Types.js +5 -0
- package/dist/schemas/Types.js.map +1 -0
- package/dist/schemas/Viewport.d.ts +74 -0
- package/dist/schemas/Viewport.d.ts.map +1 -0
- package/dist/schemas/Viewport.js +63 -0
- package/dist/schemas/Viewport.js.map +1 -0
- package/dist/schemas/index.d.ts +10 -70
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +7 -60
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/themeLibrary.d.ts +41 -0
- package/dist/schemas/themeLibrary.d.ts.map +1 -0
- package/dist/schemas/themeLibrary.js +466 -0
- package/dist/schemas/themeLibrary.js.map +1 -0
- package/dist/spatial/Geohash.d.ts +85 -0
- package/dist/spatial/Geohash.d.ts.map +1 -0
- package/dist/spatial/Geohash.js +142 -0
- package/dist/spatial/Geohash.js.map +1 -0
- package/dist/spatial/Haversine.d.ts +24 -0
- package/dist/spatial/Haversine.d.ts.map +1 -0
- package/dist/spatial/Haversine.js +48 -0
- package/dist/spatial/Haversine.js.map +1 -0
- package/dist/spatial/index.d.ts +3 -111
- package/dist/spatial/index.d.ts.map +1 -0
- package/dist/spatial/index.js +2 -24
- package/dist/spatial/index.js.map +1 -1
- package/dist/storage/ContentContainer.d.ts +87 -0
- package/dist/storage/ContentContainer.d.ts.map +1 -0
- package/dist/storage/ContentContainer.js +122 -0
- package/dist/storage/ContentContainer.js.map +1 -0
- package/dist/storage/LocalForageAdapter.d.ts +36 -0
- package/dist/storage/LocalForageAdapter.d.ts.map +1 -0
- package/dist/storage/LocalForageAdapter.js +82 -0
- package/dist/storage/LocalForageAdapter.js.map +1 -0
- package/dist/storage/LocalStorageAdapter.d.ts +16 -0
- package/dist/storage/LocalStorageAdapter.d.ts.map +1 -0
- package/dist/storage/LocalStorageAdapter.js +50 -0
- package/dist/storage/LocalStorageAdapter.js.map +1 -0
- package/dist/storage/MediaProviderFromContainer.d.ts +21 -0
- package/dist/storage/MediaProviderFromContainer.d.ts.map +1 -0
- package/dist/storage/MediaProviderFromContainer.js +79 -0
- package/dist/storage/MediaProviderFromContainer.js.map +1 -0
- package/dist/storage/MemoryStorageAdapter.d.ts +15 -0
- package/dist/storage/MemoryStorageAdapter.d.ts.map +1 -0
- package/dist/storage/MemoryStorageAdapter.js +34 -0
- package/dist/storage/MemoryStorageAdapter.js.map +1 -0
- package/dist/storage/Storage.d.ts +23 -0
- package/dist/storage/Storage.d.ts.map +1 -0
- package/dist/storage/Storage.js +9 -0
- package/dist/storage/Storage.js.map +1 -0
- package/dist/storage/index.d.ts +9 -91
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -10
- package/dist/storage/index.js.map +1 -1
- package/dist/story/index.d.ts +3 -2
- package/dist/themeLibrary-DR1VRo-8.d.ts +44 -0
- package/dist/timing/index.d.ts +4 -0
- package/dist/timing/index.d.ts.map +1 -0
- package/dist/timing/index.js +3 -0
- package/dist/timing/index.js.map +1 -0
- package/dist/timing/narrationTiming.d.ts +54 -0
- package/dist/timing/narrationTiming.d.ts.map +1 -0
- package/dist/timing/narrationTiming.js +190 -0
- package/dist/timing/narrationTiming.js.map +1 -0
- package/dist/timing/readingTime.d.ts +54 -0
- package/dist/timing/readingTime.d.ts.map +1 -0
- package/dist/timing/readingTime.js +49 -0
- package/dist/timing/readingTime.js.map +1 -0
- package/package.json +17 -3
- package/src/__tests__/contentContainer.test.ts +282 -0
- package/src/__tests__/contentExtractor.test.ts +183 -0
- package/src/__tests__/seededRandom.test.ts +142 -0
- package/src/__tests__/slideshowGenerator.test.ts +128 -0
- package/src/__tests__/timing.test.ts +167 -0
- package/src/generate/contentExtractor.ts +808 -0
- package/src/generate/index.ts +21 -0
- package/src/generate/slideshowGenerator.ts +273 -0
- package/src/generate/templateMapper.ts +170 -0
- package/src/index.ts +3 -0
- package/src/random/SeededRandom.ts +127 -0
- package/src/random/index.ts +1 -0
- package/src/storage/ContentContainer.ts +200 -0
- package/src/storage/MediaProviderFromContainer.ts +92 -0
- package/src/storage/index.ts +3 -0
- package/src/timing/index.ts +17 -0
- package/src/timing/narrationTiming.ts +220 -0
- package/src/timing/readingTime.ts +94 -0
- package/dist/chunk-VJN7UB2Z.js +0 -145
- package/dist/chunk-VJN7UB2Z.js.map +0 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { generateSlideshow, type SlideshowImage } from '../generate/index.js';
|
|
3
|
+
import { isTemplateBlock } from '../schemas/BlockTemplates.js';
|
|
4
|
+
|
|
5
|
+
const ARTICLE_TEXT = [
|
|
6
|
+
'Mount Rainier is the largest volcano in the Cascades, standing at 14,411 feet.',
|
|
7
|
+
'In July 1899, President McKinley signed the act establishing Mount Rainier National Park.',
|
|
8
|
+
'The park encompasses roughly 236,381 acres of old-growth forest and alpine meadows.',
|
|
9
|
+
'"The mountain was calling me," wrote John Muir after his 1888 expedition to explore the glaciers.',
|
|
10
|
+
'Temperatures range from 20 degrees to 70 degrees depending on elevation and season.',
|
|
11
|
+
'Popular activities including hiking, camping, fishing, and climbing draw visitors year-round.',
|
|
12
|
+
'Paradise is a popular visitor area known for its wildflower meadows and spectacular views.',
|
|
13
|
+
'The mountain has 25 named glaciers covering about 35 square miles of ice.',
|
|
14
|
+
'Rainier is the most glaciated peak in the lower 48 states, a remarkable natural wonder.',
|
|
15
|
+
'Imagine standing above the clouds at sunrise!',
|
|
16
|
+
].join('\n\n');
|
|
17
|
+
|
|
18
|
+
const SAMPLE_IMAGES: SlideshowImage[] = [
|
|
19
|
+
{ src: '/img/rainier-1.jpg', alt: 'Mount Rainier from Paradise' },
|
|
20
|
+
{ src: '/img/rainier-2.jpg', alt: 'Wildflower meadow', credit: 'NPS Photo' },
|
|
21
|
+
{ src: '/img/rainier-3.jpg', alt: 'Nisqually Glacier' },
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
describe('generateSlideshow', () => {
|
|
25
|
+
it('produces a valid Doc with blocks', () => {
|
|
26
|
+
const doc = generateSlideshow(ARTICLE_TEXT);
|
|
27
|
+
expect(doc.blocks.length).toBeGreaterThan(0);
|
|
28
|
+
expect(doc.duration).toBeGreaterThan(0);
|
|
29
|
+
expect(doc.articleId).toBe('slideshow');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('includes a title slide when title is provided', () => {
|
|
33
|
+
const doc = generateSlideshow(ARTICLE_TEXT, [], { title: 'Mount Rainier' });
|
|
34
|
+
expect(doc.articleId).toBe('Mount Rainier');
|
|
35
|
+
const first = doc.blocks[0];
|
|
36
|
+
if (isTemplateBlock(first)) {
|
|
37
|
+
expect(first.template).toBe('titleBlock');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('embeds themeId in the Doc', () => {
|
|
42
|
+
const doc = generateSlideshow(ARTICLE_TEXT, [], { themeId: 'cinematic' });
|
|
43
|
+
expect(doc.themeId).toBe('cinematic');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('interleaves image slides when images are provided', () => {
|
|
47
|
+
const doc = generateSlideshow(ARTICLE_TEXT, SAMPLE_IMAGES);
|
|
48
|
+
const imageSlides = doc.blocks.filter(
|
|
49
|
+
(b) => isTemplateBlock(b) && b.template === 'imageWithCaption',
|
|
50
|
+
);
|
|
51
|
+
expect(imageSlides.length).toBeGreaterThan(0);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('produces deterministic output with the same seed', () => {
|
|
55
|
+
const a = generateSlideshow(ARTICLE_TEXT, SAMPLE_IMAGES, { seed: 42 });
|
|
56
|
+
const b = generateSlideshow(ARTICLE_TEXT, SAMPLE_IMAGES, { seed: 42 });
|
|
57
|
+
expect(a.blocks.length).toBe(b.blocks.length);
|
|
58
|
+
for (let i = 0; i < a.blocks.length; i++) {
|
|
59
|
+
if (isTemplateBlock(a.blocks[i]) && isTemplateBlock(b.blocks[i])) {
|
|
60
|
+
const aBlock = a.blocks[i] as { template: string };
|
|
61
|
+
const bBlock = b.blocks[i] as { template: string };
|
|
62
|
+
expect(aBlock.template).toBe(bBlock.template);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('produces different output with different seeds', () => {
|
|
68
|
+
const a = generateSlideshow(ARTICLE_TEXT, SAMPLE_IMAGES, { seed: 1 });
|
|
69
|
+
const b = generateSlideshow(ARTICLE_TEXT, SAMPLE_IMAGES, { seed: 999 });
|
|
70
|
+
// At least some image accents or motions should differ
|
|
71
|
+
const aSerialized = JSON.stringify(a.blocks);
|
|
72
|
+
const bSerialized = JSON.stringify(b.blocks);
|
|
73
|
+
// They should differ in at least some detail (ambient motions, accent positions)
|
|
74
|
+
expect(aSerialized).not.toBe(bSerialized);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('handles empty text gracefully', () => {
|
|
78
|
+
const doc = generateSlideshow('', []);
|
|
79
|
+
expect(doc.blocks.length).toBe(0);
|
|
80
|
+
expect(doc.duration).toBe(0);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('handles markdown input when isMarkdown is set', () => {
|
|
84
|
+
const md = '# Title\n\nThe park covers **236,381 acres** of wilderness.';
|
|
85
|
+
const doc = generateSlideshow(md, [], { isMarkdown: true });
|
|
86
|
+
expect(doc.blocks.length).toBeGreaterThan(0);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('uses explicit duration when provided', () => {
|
|
90
|
+
const doc = generateSlideshow(ARTICLE_TEXT, [], { duration: 60 });
|
|
91
|
+
expect(doc.duration).toBe(60);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('respects targetSlides option', () => {
|
|
95
|
+
const doc = generateSlideshow(ARTICLE_TEXT, [], { targetSlides: 3 });
|
|
96
|
+
// Should have ~3 slides (may be slightly more due to title, images)
|
|
97
|
+
expect(doc.blocks.length).toBeLessThanOrEqual(5);
|
|
98
|
+
expect(doc.blocks.length).toBeGreaterThan(0);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('every block has an id and duration', () => {
|
|
102
|
+
const doc = generateSlideshow(ARTICLE_TEXT, SAMPLE_IMAGES, { title: 'Test' });
|
|
103
|
+
for (const block of doc.blocks) {
|
|
104
|
+
if (isTemplateBlock(block)) {
|
|
105
|
+
expect(block.id).toBeTruthy();
|
|
106
|
+
expect(block.duration).toBeGreaterThan(0);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('rotates color schemes across content slides', () => {
|
|
112
|
+
const doc = generateSlideshow(ARTICLE_TEXT, [], {
|
|
113
|
+
colorSchemes: ['blue', 'green'],
|
|
114
|
+
targetSlides: 6,
|
|
115
|
+
});
|
|
116
|
+
const colors: string[] = [];
|
|
117
|
+
for (const block of doc.blocks) {
|
|
118
|
+
if (isTemplateBlock(block) && 'colorScheme' in block) {
|
|
119
|
+
const cs = (block as { colorScheme?: string }).colorScheme;
|
|
120
|
+
if (cs) colors.push(cs);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// With 2 schemes, we should see alternation
|
|
124
|
+
if (colors.length >= 2) {
|
|
125
|
+
expect(colors[0]).not.toBe(colors[1]);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
countSpokenWords,
|
|
4
|
+
estimateSpokenWordCount,
|
|
5
|
+
estimateTimeFromText,
|
|
6
|
+
calculatePrefixDuration,
|
|
7
|
+
estimateNarrationDuration,
|
|
8
|
+
estimateReadingTime,
|
|
9
|
+
estimateNarrationTime,
|
|
10
|
+
DEFAULT_WORDS_PER_SECOND,
|
|
11
|
+
} from '../timing/index.js';
|
|
12
|
+
|
|
13
|
+
// ── narrationTiming ────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
describe('estimateSpokenWordCount', () => {
|
|
16
|
+
it('counts a regular word as 1', () => {
|
|
17
|
+
expect(estimateSpokenWordCount('hello')).toBe(1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('expands a small number (50 → "fifty" → 1 word × 1.3)', () => {
|
|
21
|
+
expect(estimateSpokenWordCount('50')).toBeCloseTo(1.3);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('expands a year (1910 → "nineteen ten" → 2 × 1.3)', () => {
|
|
25
|
+
expect(estimateSpokenWordCount('1910')).toBeCloseTo(2.6);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('expands a large number (175000)', () => {
|
|
29
|
+
// "one hundred seventy-five" (4 words) + "thousand" (1) = 5 words × 1.3
|
|
30
|
+
expect(estimateSpokenWordCount('175000')).toBeCloseTo(6.5, 1);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('handles 2024 as a year', () => {
|
|
34
|
+
// "twenty twenty-four" → 3 words × 1.3
|
|
35
|
+
expect(estimateSpokenWordCount('2024')).toBeCloseTo(3.9);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('handles zero', () => {
|
|
39
|
+
// "zero" → 1 word × 1.3
|
|
40
|
+
expect(estimateSpokenWordCount('0')).toBeCloseTo(1.3);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('handles non-numeric strings', () => {
|
|
44
|
+
expect(estimateSpokenWordCount('hello')).toBe(1);
|
|
45
|
+
expect(estimateSpokenWordCount('')).toBe(1);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('countSpokenWords', () => {
|
|
50
|
+
it('counts plain text words', () => {
|
|
51
|
+
expect(countSpokenWords('the quick brown fox')).toBe(4);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('includes comma pause penalties', () => {
|
|
55
|
+
const withComma = countSpokenWords('hello, world');
|
|
56
|
+
const without = countSpokenWords('hello world');
|
|
57
|
+
expect(withComma).toBeGreaterThan(without);
|
|
58
|
+
expect(withComma - without).toBeCloseTo(0.3);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('expands numbers within text', () => {
|
|
62
|
+
const result = countSpokenWords('In 1910 there were 50 houses');
|
|
63
|
+
// "In"(1) + "1910"(2.6) + "there"(1) + "were"(1) + "50"(1.3) + "houses"(1)
|
|
64
|
+
expect(result).toBeCloseTo(7.9);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('returns 0 for empty text', () => {
|
|
68
|
+
expect(countSpokenWords('')).toBe(0);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('estimateTimeFromText', () => {
|
|
73
|
+
it('returns 0 at the beginning', () => {
|
|
74
|
+
expect(estimateTimeFromText('hello world', 0, 10)).toBe(0);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('returns proportional time at the midpoint', () => {
|
|
78
|
+
const time = estimateTimeFromText('one two three four', 8, 20);
|
|
79
|
+
// "one two" = 2 words before offset 8, total = 4 words → 50% → 10s
|
|
80
|
+
expect(time).toBeCloseTo(10);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('returns totalDuration at the end', () => {
|
|
84
|
+
const text = 'some text here';
|
|
85
|
+
const time = estimateTimeFromText(text, text.length, 30);
|
|
86
|
+
expect(time).toBeCloseTo(30);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('returns 0 for empty text', () => {
|
|
90
|
+
expect(estimateTimeFromText('', 0, 10)).toBe(0);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('calculatePrefixDuration', () => {
|
|
95
|
+
it('returns 0 for empty string', () => {
|
|
96
|
+
expect(calculatePrefixDuration('')).toBe(0);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('estimates based on word count', () => {
|
|
100
|
+
// 5 words at 2.5 wps = 2 seconds
|
|
101
|
+
expect(calculatePrefixDuration('one two three four five')).toBeCloseTo(2);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('adds pause time for paragraph breaks', () => {
|
|
105
|
+
const withBreak = calculatePrefixDuration('Title\n\nContent here');
|
|
106
|
+
const without = calculatePrefixDuration('Title Content here');
|
|
107
|
+
expect(withBreak).toBeGreaterThan(without);
|
|
108
|
+
// One paragraph break → +0.5s
|
|
109
|
+
expect(withBreak - without).toBeCloseTo(0.5);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe('estimateNarrationDuration', () => {
|
|
114
|
+
it('estimates simple text', () => {
|
|
115
|
+
// 5 words at 2.5 wps = 2 seconds
|
|
116
|
+
expect(estimateNarrationDuration('one two three four five')).toBeCloseTo(2);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('accepts custom rate', () => {
|
|
120
|
+
// 5 words at 5 wps = 1 second
|
|
121
|
+
expect(estimateNarrationDuration('one two three four five', 5)).toBeCloseTo(1);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// ── readingTime ────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
describe('estimateReadingTime', () => {
|
|
128
|
+
it('estimates 200-word text at 1 minute', () => {
|
|
129
|
+
const text = Array(200).fill('word').join(' ');
|
|
130
|
+
const result = estimateReadingTime(text);
|
|
131
|
+
expect(result.words).toBe(200);
|
|
132
|
+
expect(result.minutes).toBeCloseTo(1);
|
|
133
|
+
expect(result.seconds).toBe(60);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('respects custom WPM', () => {
|
|
137
|
+
const text = Array(100).fill('word').join(' ');
|
|
138
|
+
const result = estimateReadingTime(text, { wordsPerMinute: 100 });
|
|
139
|
+
expect(result.minutes).toBeCloseTo(1);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('returns 0 for empty text', () => {
|
|
143
|
+
const result = estimateReadingTime('');
|
|
144
|
+
expect(result.words).toBe(0);
|
|
145
|
+
expect(result.seconds).toBe(0);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
describe('estimateNarrationTime', () => {
|
|
150
|
+
it('accounts for number expansion', () => {
|
|
151
|
+
const plain = estimateNarrationTime('five words in this text');
|
|
152
|
+
const withNum = estimateNarrationTime('In 1910 there were 50 houses');
|
|
153
|
+
// Numbers add more spoken-word equivalents
|
|
154
|
+
expect(withNum.spokenWords).toBeGreaterThan(plain.spokenWords);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('returns reasonable seconds', () => {
|
|
158
|
+
const result = estimateNarrationTime('one two three four five');
|
|
159
|
+
expect(result.seconds).toBe(2); // 5 words / 2.5 wps = 2s
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe('DEFAULT_WORDS_PER_SECOND', () => {
|
|
164
|
+
it('is 2.5', () => {
|
|
165
|
+
expect(DEFAULT_WORDS_PER_SECOND).toBe(2.5);
|
|
166
|
+
});
|
|
167
|
+
});
|