11import githubCode from '../../testdata/generated/github.html'
22import sourcegraphCode from '../../testdata/generated/sourcegraph.html'
3- import { DOMOptions , getTextNodes } from '../token_position'
3+ import { DOMFunctions } from '../token_position'
44import { TEST_DATA_REVSPEC } from './rev'
55
6- const createElementFromString = ( html : string ) : HTMLElement => {
6+ const createElementFromString = ( html : string ) : HTMLDivElement => {
77 const elem = document . createElement ( 'div' )
88
99 elem . innerHTML = html
@@ -17,43 +17,30 @@ const createElementFromString = (html: string): HTMLElement => {
1717 return elem
1818}
1919
20- export const getCharacterWidth = ( character : string ) : number =>
21- createElementFromString ( character ) . getBoundingClientRect ( ) . width
20+ /** Gets all of the text nodes within a given node. Used for testing. */
21+ export const getTextNodes = ( node : Node ) : Node [ ] => {
22+ if ( node . childNodes . length === 0 && node . TEXT_NODE === node . nodeType && node . nodeValue ) {
23+ return [ node ]
24+ }
2225
23- export const getCharacterWidthInContainer = ( container : HTMLElement , character : string , idx : number ) : number => {
24- const span = document . createElement ( 'span' )
25- span . innerHTML = character
26- span . dataset . char = idx + ''
27- span . dataset . charCode = character . charCodeAt ( 0 ) + ''
28- span . style . visibility = 'hidden'
29- span . style . cssFloat = 'left'
30- span . style . height = '0'
26+ const nodes : Node [ ] = [ ]
3127
32- container . appendChild ( span )
33- const width = span . getBoundingClientRect ( ) . width
34- container . removeChild ( span )
28+ for ( const child of Array . from ( node . childNodes ) ) {
29+ nodes . push ( ... getTextNodes ( child ) )
30+ }
3531
36- return width
32+ return nodes
3733}
3834
39- const getCharactersInCell = ( cell : HTMLElement ) =>
40- Array . from (
41- getTextNodes ( cell )
42- . map ( node => node . nodeValue )
43- . join ( '' )
44- )
45-
46- export const getNumberOfCharactersFromCell = ( cell : HTMLElement ) : number => getCharactersInCell ( cell ) . length
47- export const getWidthOfCharactersFromCell = ( cell : HTMLElement ) : number =>
48- getCharactersInCell ( cell )
49- . map ( ( c , i ) => getCharacterWidthInContainer ( cell , c , i ) )
50- . reduce ( ( a , b ) => a + b , 0 )
51-
52- export interface CodeViewProps extends DOMOptions {
53- element : HTMLElement
54- injectedElement : HTMLElement
35+ /** The props used for the generated test cases(e.g. GitHub and Sourcegraph flavored dom). */
36+ export interface CodeViewProps extends DOMFunctions {
37+ /** The code view for the given test case(e.g. a <code> element in Sourcegraph and <table> in GitHub) */
38+ codeView : HTMLElement
39+ /** The container of the code view. (e.g. The scrollable contaienr in Sourcegraph and a parent <div> in GitHub) */
40+ container : HTMLElement
41+ /** The revision and repository information for the file used in the generated test cases. */
5542 revSpec : typeof TEST_DATA_REVSPEC
56-
43+ /** A helper method for adding rows to the test case. */
5744 insertRow : ( text : string ) => HTMLElement
5845}
5946
@@ -62,6 +49,8 @@ export const wrapCharsInSpans = (line: string) =>
6249 . map ( ( c , j ) => `<span data-char="${ j } ">${ c } </span>` )
6350 . join ( '' )
6451
52+ // BEGIN setup test cases
53+
6554const getDiffCodePart = ( codeElement : HTMLElement ) : 'new' | 'old' | undefined => {
6655 switch ( codeElement . textContent ! . charAt ( 0 ) ) {
6756 case '+' :
@@ -123,8 +112,8 @@ const createGitHubCodeView = (): CodeViewProps => {
123112 }
124113
125114 return {
126- injectedElement : codeView ,
127- element : codeView ,
115+ container : codeView ,
116+ codeView,
128117
129118 revSpec : TEST_DATA_REVSPEC ,
130119 getCodeElementFromTarget,
@@ -204,9 +193,9 @@ const createSourcegraphCodeView = (): CodeViewProps => {
204193 }
205194
206195 return {
207- injectedElement : codeView ,
196+ container : codeView ,
208197
209- element : codeView . querySelector ( 'code' ) ! ,
198+ codeView : codeView . querySelector ( 'code' ) ! ,
210199 revSpec : TEST_DATA_REVSPEC ,
211200 getCodeElementFromTarget,
212201 getCodeElementFromLineNumber,
@@ -231,31 +220,51 @@ const createSourcegraphCodeView = (): CodeViewProps => {
231220 }
232221}
233222
223+ // END setup test cases
224+
225+ /**
226+ * DOM is a testing utility class that keeps track of all elements a test suite is adding to the DOM
227+ * so that we can clean up after the test suite has finished.
228+ */
234229export class DOM {
230+ /** The inserted nodes. We save them so that we can remove them on cleanup. */
235231 private nodes = new Set < Element > ( )
236232
233+ /**
234+ * Creates and inserts the generated test cases into the DOM
235+ * @returns the CodeViewProps for the test cases added to the DOM.
236+ */
237237 public createCodeViews ( ) : CodeViewProps [ ] {
238238 const codeViews : CodeViewProps [ ] = [ createSourcegraphCodeView ( ) , createGitHubCodeView ( ) ]
239239
240- for ( const { injectedElement } of codeViews ) {
241- this . insert ( injectedElement )
240+ for ( const { container } of codeViews ) {
241+ this . insert ( container )
242242 }
243243
244244 return codeViews
245245 }
246246
247- public createElementFromString ( html : string ) : HTMLElement {
247+ /**
248+ * Creates a div with some arbitrary content.
249+ * @param html the content of the element you wish to create.
250+ * @returns the created div.
251+ */
252+ public createElementFromString ( html : string ) : HTMLDivElement {
248253 const element = createElementFromString ( html )
249254 this . insert ( element )
250- return element as HTMLElement
255+ return element as HTMLDivElement
251256 }
252257
258+ /**
259+ * Removes all nodes that were inserted from the DOM. This should be called after a test suite has ran.
260+ */
253261 public cleanup = ( ) : void => {
254262 for ( const node of this . nodes ) {
255263 document . body . removeChild ( node )
256264 }
257265 }
258266
267+ /** The funnel for inserting elements into the DOM so that we know to remove it in `cleanup()`. */
259268 private insert ( node : Element ) : void {
260269 document . body . appendChild ( node )
261270
0 commit comments