@@ -7,9 +7,13 @@ import {
77 normalizeBasePath ,
88 normalizeGitHubStars ,
99 normalizeOrigin ,
10+ parseChangelog ,
11+ parseChangeset ,
12+ renderChangelogPage ,
1013 renderIndexPage ,
1114 renderLayout ,
1215 renderMarkdown ,
16+ renderModulePage ,
1317 renderRobots ,
1418 renderSitemap ,
1519 siteManifest ,
@@ -30,6 +34,22 @@ test("renders documentation prose while escaping source HTML", () => {
3034 assert . doesNotMatch ( renderMarkdown ( "<script>alert(1)</script>" ) , / < s c r i p t > / )
3135} )
3236
37+ test ( "renders fenced code with highlighting and copy controls" , ( ) => {
38+ const html = renderMarkdown ( `Call the new API:
39+
40+ \`\`\`ts
41+ const value = Machine.example("safe")
42+ \`\`\`
43+
44+ Then reuse \`value\`.` )
45+ assert . match ( html , / < p > C a l l t h e n e w A P I : < \/ p > / )
46+ assert . match ( html , / c l a s s = " c o d e - b l o c k c o d e - b l o c k - - m a r k d o w n " / )
47+ assert . match ( html , / a r i a - l a b e l = " C o p y t s c o d e " / )
48+ assert . match ( html , / s y n t a x - k e y w o r d " > c o n s t < \/ s p a n > / )
49+ assert . match ( html , / s y n t a x - s t r i n g " > & q u o t ; s a f e & q u o t ; < \/ s p a n > / )
50+ assert . match ( html , / < p > T h e n r e u s e < c o d e > v a l u e < \/ c o d e > \. < \/ p > / )
51+ } )
52+
3353test ( "assigns deterministic unique anchors to duplicate declarations" , ( ) => {
3454 const first = { name : "Machine" }
3555 const second = { name : "Machine" }
@@ -88,6 +108,92 @@ const site = {
88108 title : "Effect Machine"
89109}
90110
111+ test ( "parses Changesets release entries and pending descriptions" , ( ) => {
112+ const releases = parseChangelog ( `# Package
113+
114+ ## 1.2.0
115+
116+ ### Minor Changes
117+
118+ - abc1234: Add a typed \`make\` helper.
119+
120+ Preserve inference across multiple lines.
121+
122+ \`\`\`ts
123+ const machine = make()
124+ \`\`\`
125+
126+ ### Patch Changes
127+
128+ - def5678: Fix escaped output.
129+ ` , new Map ( [ [ "1.2.0" , "2026-08-13" ] ] ) )
130+ assert . deepEqual ( releases , [ {
131+ version : "1.2.0" ,
132+ date : "2026-08-13" ,
133+ groups : [ {
134+ type : "minor" ,
135+ entries : [ {
136+ description : "Add a typed `make` helper.\n\nPreserve inference across multiple lines.\n\n```ts\nconst machine = make()\n```"
137+ } ]
138+ } , {
139+ type : "patch" ,
140+ entries : [ { description : "Fix escaped output." } ]
141+ } ]
142+ } ] )
143+ assert . deepEqual ( parseChangeset ( `---
144+ "@typeonce/effect-machine": minor
145+ ---
146+
147+ Add snapshot selectors.
148+ ` , "@typeonce/effect-machine" ) , { type : "minor" , description : "Add snapshot selectors." } )
149+ assert . equal ( parseChangeset ( `---
150+ "another-package": patch
151+ ---
152+
153+ Ignore this package.
154+ ` , "@typeonce/effect-machine" ) , undefined )
155+ } )
156+
157+ test ( "renders a navigable changelog with release dates" , ( ) => {
158+ const html = renderChangelogPage ( {
159+ ...site ,
160+ changelog : [ {
161+ version : "1.2.0" ,
162+ date : "2026-08-13" ,
163+ groups : [ { type : "minor" , entries : [ { description : "Add a feature." } ] } ]
164+ } ]
165+ } )
166+ assert . match ( html , / c l a s s = " n a v i g a t i o n - c h a n g e l o g i s - c u r r e n t " / )
167+ assert . match ( html , / i d = " r e l e a s e - 1 - 2 - 0 " > v 1 \. 2 \. 0 / )
168+ assert . match ( html , / d a t e t i m e = " 2 0 2 6 - 0 8 - 1 3 " > A u g u s t 1 3 , 2 0 2 6 / )
169+ assert . match ( html , / < l i > < p > A d d a f e a t u r e \. < \/ p > < \/ l i > / )
170+ } )
171+
172+ test ( "renders collapsible category navigation with declaration anchors" , ( ) => {
173+ const declaration = {
174+ name : "make" ,
175+ kind : "variable" ,
176+ description : "Creates a machine." ,
177+ examples : [ ] ,
178+ see : [ ]
179+ }
180+ const module = {
181+ api : {
182+ declarationCount : 1 ,
183+ description : "State machine APIs" ,
184+ groups : [ { category : "constructors" , declarations : [ declaration ] } ]
185+ } ,
186+ export : "./Machine" ,
187+ label : "Machine" ,
188+ route : "Machine"
189+ }
190+ const html = renderModulePage ( { ...site , modules : [ module ] } , module )
191+ assert . match ( html , / < d e t a i l s c l a s s = " p a g e - t o c _ _ g r o u p " > / )
192+ assert . match ( html , / < s u m m a r y > [ \s \S ] * C o n s t r u c t o r s [ \s \S ] * < \/ s u m m a r y > / )
193+ assert . match ( html , / < a h r e f = " # m a k e " > m a k e < \/ a > / )
194+ assert . match ( html , / < h 3 i d = " m a k e " > m a k e < \/ h 3 > / )
195+ } )
196+
91197test ( "renders canonical and social metadata without exposing the internal channel" , ( ) => {
92198 const html = renderLayout ( site , {
93199 content : '<section class="reference-hero"><div class="eyebrow">API reference</div></section>' ,
@@ -162,6 +268,7 @@ test("generates manifest, robots, and sitemap URLs from the deployment base", ()
162268 assert . equal ( manifest . icons [ 2 ] . purpose , "maskable" )
163269 assert . match ( renderRobots ( site ) , / S i t e m a p : h t t p s : \/ \/ d o c s \. e x a m p l e \. c o m \/ d o c s \/ s i t e m a p \. x m l / )
164270 assert . match ( renderSitemap ( site ) , / < l o c > h t t p s : \/ \/ d o c s \. e x a m p l e \. c o m \/ d o c s \/ M a c h i n e \/ < \/ l o c > / )
271+ assert . match ( renderSitemap ( site ) , / < l o c > h t t p s : \/ \/ d o c s \. e x a m p l e \. c o m \/ d o c s \/ c h a n g e l o g \/ < \/ l o c > / )
165272} )
166273
167274test ( "accepts only pathless HTTPS production origins" , ( ) => {
0 commit comments