55
66import * as assert from 'assert' ;
77import { activate } from '..' ;
8- import { OutputItem , RendererApi } from 'vscode-notebook-renderer' ;
9- import { IDisposable , IRichRenderContext , RenderOptions } from '../rendererTypes' ;
8+ import { RendererApi } from 'vscode-notebook-renderer' ;
9+ import { IDisposable , IRichRenderContext , OutputWithAppend , RenderOptions } from '../rendererTypes' ;
1010import { JSDOM } from "jsdom" ;
1111
1212const dom = new JSDOM ( ) ;
@@ -116,10 +116,13 @@ suite('Notebook builtin output renderer', () => {
116116 }
117117 }
118118
119- function createOutputItem ( text : string , mime : string , id : string = '123' ) : OutputItem {
119+ function createOutputItem ( text : string , mime : string , id : string = '123' , appendedText ?: string ) : OutputWithAppend {
120120 return {
121121 id : id ,
122122 mime : mime ,
123+ appendedText ( ) {
124+ return appendedText ;
125+ } ,
123126 text ( ) {
124127 return text ;
125128 } ,
@@ -177,9 +180,9 @@ suite('Notebook builtin output renderer', () => {
177180 assert . ok ( renderer , 'Renderer not created' ) ;
178181
179182 const outputElement = new OutputHtml ( ) . getFirstOuputElement ( ) ;
180- const outputItem = createOutputItem ( 'content' , 'text/plain' ) ;
183+ const outputItem = createOutputItem ( 'content' , mimeType ) ;
181184 await renderer ! . renderOutputItem ( outputItem , outputElement ) ;
182- const outputItem2 = createOutputItem ( 'replaced content' , 'text/plain' ) ;
185+ const outputItem2 = createOutputItem ( 'replaced content' , mimeType ) ;
183186 await renderer ! . renderOutputItem ( outputItem2 , outputElement ) ;
184187
185188 const inserted = outputElement . firstChild as HTMLElement ;
@@ -189,6 +192,59 @@ suite('Notebook builtin output renderer', () => {
189192
190193 } ) ;
191194
195+ test ( 'Append streaming output' , async ( ) => {
196+ const context = createContext ( { outputWordWrap : false , outputScrolling : false } ) ;
197+ const renderer = await activate ( context ) ;
198+ assert . ok ( renderer , 'Renderer not created' ) ;
199+
200+ const outputElement = new OutputHtml ( ) . getFirstOuputElement ( ) ;
201+ const outputItem = createOutputItem ( 'content' , stdoutMimeType , '123' , 'ignoredAppend' ) ;
202+ await renderer ! . renderOutputItem ( outputItem , outputElement ) ;
203+ const outputItem2 = createOutputItem ( 'content\nappended' , stdoutMimeType , '\nappended' ) ;
204+ await renderer ! . renderOutputItem ( outputItem2 , outputElement ) ;
205+
206+ const inserted = outputElement . firstChild as HTMLElement ;
207+ assert . ok ( inserted . innerHTML . indexOf ( '>content</' ) !== - 1 , `Previous content should still exist: ${ outputElement . innerHTML } ` ) ;
208+ assert . ok ( inserted . innerHTML . indexOf ( 'ignoredAppend' ) === - 1 , `Append value should not be used on first render: ${ outputElement . innerHTML } ` ) ;
209+ assert . ok ( inserted . innerHTML . indexOf ( '>appended</' ) !== - 1 , `Content was not appended to output element: ${ outputElement . innerHTML } ` ) ;
210+ assert . ok ( inserted . innerHTML . indexOf ( '>content</' ) === inserted . innerHTML . lastIndexOf ( '>content</' ) , `Original content should not be duplicated: ${ outputElement . innerHTML } ` ) ;
211+ } ) ;
212+
213+ test ( 'Append large streaming outputs' , async ( ) => {
214+ const context = createContext ( { outputWordWrap : false , outputScrolling : false } ) ;
215+ const renderer = await activate ( context ) ;
216+ assert . ok ( renderer , 'Renderer not created' ) ;
217+
218+ const outputElement = new OutputHtml ( ) . getFirstOuputElement ( ) ;
219+ const lotsOfLines = new Array ( 4998 ) . fill ( 'line' ) . join ( '\n' ) + 'endOfInitialContent' ;
220+ const firstOuput = lotsOfLines + 'expected1' ;
221+ const outputItem = createOutputItem ( firstOuput , stdoutMimeType , '123' ) ;
222+ await renderer ! . renderOutputItem ( outputItem , outputElement ) ;
223+ const appended = '\n' + lotsOfLines + 'expectedAppend' ;
224+ const outputItem2 = createOutputItem ( firstOuput + appended , stdoutMimeType , appended ) ;
225+ await renderer ! . renderOutputItem ( outputItem2 , outputElement ) ;
226+
227+ const inserted = outputElement . firstChild as HTMLElement ;
228+ assert . ok ( inserted . innerHTML . indexOf ( '>expected1</' ) !== - 1 , `Last bit of previous content should still exist: ${ outputElement . innerHTML } ` ) ;
229+ assert . ok ( inserted . innerHTML . indexOf ( '>expectedAppend</' ) !== - 1 , `Content was not appended to output element: ${ outputElement . innerHTML } ` ) ;
230+ } ) ;
231+
232+ test ( 'Streaming outputs larger than the line limit are truncated' , async ( ) => {
233+ const context = createContext ( { outputWordWrap : false , outputScrolling : false } ) ;
234+ const renderer = await activate ( context ) ;
235+ assert . ok ( renderer , 'Renderer not created' ) ;
236+
237+ const outputElement = new OutputHtml ( ) . getFirstOuputElement ( ) ;
238+ const lotsOfLines = new Array ( 11000 ) . fill ( 'line' ) . join ( '\n' ) + 'endOfInitialContent' ;
239+ const firstOuput = 'shouldBeTruncated' + lotsOfLines + 'expected1' ;
240+ const outputItem = createOutputItem ( firstOuput , stdoutMimeType , '123' ) ;
241+ await renderer ! . renderOutputItem ( outputItem , outputElement ) ;
242+
243+ const inserted = outputElement . firstChild as HTMLElement ;
244+ assert . ok ( inserted . innerHTML . indexOf ( '>endOfInitialContent</' ) !== - 1 , `Last bit of content should exist: ${ outputElement . innerHTML } ` ) ;
245+ assert . ok ( inserted . innerHTML . indexOf ( '>shouldBeTruncated</' ) === - 1 , `Beginning content should be truncated: ${ outputElement . innerHTML } ` ) ;
246+ } ) ;
247+
192248 test ( `Render with wordwrap and scrolling for error output` , async ( ) => {
193249 const context = createContext ( { outputWordWrap : true , outputScrolling : true } ) ;
194250 const renderer = await activate ( context ) ;
0 commit comments