1- import { Prism } from '../prismSetup' ;
1+ import { ensureYamlSqlExtensions , Prism } from '../prismSetup' ;
22
33describe ( 'Prism diff-highlight plugin' , ( ) => {
44 const code = `+console.log('hi');\n-const a = 1;` ;
@@ -223,6 +223,8 @@ describe('Prism diff-highlight plugin', () => {
223223 } ) ;
224224
225225 test ( 'YAML grammar supports SQL highlighting in sql fields' , ( ) => {
226+ ensureYamlSqlExtensions ( ) ;
227+
226228 const yamlCode = `cubes:
227229 - name: orders
228230 sql: SELECT id, name FROM orders WHERE active = 1
@@ -243,6 +245,8 @@ describe('Prism diff-highlight plugin', () => {
243245 } ) ;
244246
245247 test ( 'YAML grammar supports SQL highlighting in multiline folded blocks' , ( ) => {
248+ ensureYamlSqlExtensions ( ) ;
249+
246250 const yamlCode = `cubes:
247251 - name: orders
248252 sql: >
@@ -261,4 +265,125 @@ describe('Prism diff-highlight plugin', () => {
261265 expect ( hasKeywords ) . toBe ( true ) ;
262266 expect ( hasSqlKeywords ) . toBe ( true ) ;
263267 } ) ;
268+
269+ test ( 'PrismDiffCode with YAML containing multiline SQL blocks' , ( ) => {
270+ ensureYamlSqlExtensions ( ) ;
271+
272+ // Test that PrismDiffCode properly handles YAML with multiline SQL
273+ const { diffLines } = require ( 'diff' ) ;
274+
275+ const originalYaml = `cubes:
276+ - name: orders
277+ sql: >
278+ SELECT id, amount, status
279+ FROM orders
280+ WHERE active = 1
281+ measures:
282+ - name: count
283+ type: count` ;
284+
285+ const modifiedYaml = `cubes:
286+ - name: orders
287+ sql: >
288+ SELECT id, amount, status, created_at
289+ FROM orders
290+ WHERE active = 1 AND status != 'cancelled'
291+ measures:
292+ - name: count
293+ type: count
294+ - name: total_amount
295+ sql: amount
296+ type: sum` ;
297+
298+ const diff = diffLines ( originalYaml , modifiedYaml ) ;
299+ const diffString = diff
300+ . map ( ( part : any ) => {
301+ const value = part . value . trimEnd ( ) ;
302+ if ( part . added ) {
303+ return value
304+ . split ( '\n' )
305+ . map ( ( val : string ) => ( val ? `+${ val } ` : '' ) )
306+ . join ( '\n' ) ;
307+ }
308+ if ( part . removed ) {
309+ return value
310+ . split ( '\n' )
311+ . map ( ( val : string ) => ( val ? `-${ val } ` : '' ) )
312+ . join ( '\n' ) ;
313+ }
314+ return value
315+ . split ( '\n' )
316+ . map ( ( val : string ) => ( val ? ` ${ val } ` : '' ) )
317+ . join ( '\n' ) ;
318+ } )
319+ . join ( '\n' ) ;
320+
321+ // Capture tokens from diff-yaml processing
322+ let capturedTokens : any ;
323+ const originalHook =
324+ Prism . hooks . all [ 'after-tokenize' ] [
325+ Prism . hooks . all [ 'after-tokenize' ] . length - 1
326+ ] ;
327+ Prism . hooks . all [ 'after-tokenize' ] [
328+ Prism . hooks . all [ 'after-tokenize' ] . length - 1
329+ ] = function ( env : any ) {
330+ originalHook . call ( this , env ) ;
331+ if ( env . language === 'diff-yaml' ) {
332+ capturedTokens = env . tokens ;
333+ }
334+ } ;
335+
336+ // Manually register diff-yaml like PrismDiffCode would
337+ if ( ! Prism . languages [ 'diff-yaml' ] ) {
338+ Prism . languages [ 'diff-yaml' ] = Prism . languages . diff ;
339+ }
340+
341+ // Process the diff string with diff-yaml language
342+ Prism . highlight ( diffString , Prism . languages . diff , 'diff-yaml' ) ;
343+
344+ expect ( capturedTokens ) . toBeDefined ( ) ;
345+
346+ // Check that we have diff tokens (added/removed lines)
347+ const hasAddedTokens = capturedTokens . some (
348+ ( t : any ) => typeof t !== 'string' && t . type === 'inserted-sign' ,
349+ ) ;
350+ const hasRemovedTokens = capturedTokens . some (
351+ ( t : any ) => typeof t !== 'string' && t . type === 'deleted-sign' ,
352+ ) ;
353+
354+ expect ( hasAddedTokens ) . toBe ( true ) ;
355+ expect ( hasRemovedTokens ) . toBe ( true ) ;
356+
357+ // Check that within the diff tokens, we have nested YAML and SQL highlighting
358+ const diffTokens = capturedTokens . filter (
359+ ( t : any ) =>
360+ typeof t !== 'string' &&
361+ ( t . type === 'inserted-sign' || t . type === 'deleted-sign' ) ,
362+ ) ;
363+
364+ // Look for nested SQL tokens within the YAML content
365+ const hasNestedSqlHighlighting = diffTokens . some ( ( token : any ) => {
366+ const lineTokens = Array . isArray ( token . content )
367+ ? token . content . filter (
368+ ( c : any ) => typeof c !== 'string' && c . type === 'line' ,
369+ )
370+ : [ ] ;
371+
372+ return lineTokens . some ( ( lineToken : any ) => {
373+ if ( ! Array . isArray ( lineToken . content ) ) return false ;
374+
375+ // Check for SQL keywords, YAML keys, or sql-scalar tokens
376+ const tokenString = JSON . stringify ( lineToken . content ) ;
377+ return (
378+ ( tokenString . includes ( '"keyword"' ) &&
379+ ( tokenString . includes ( 'SELECT' ) ||
380+ tokenString . includes ( 'WHERE' ) ||
381+ tokenString . includes ( 'FROM' ) ) ) ||
382+ tokenString . includes ( '"sql-scalar"' )
383+ ) ;
384+ } ) ;
385+ } ) ;
386+
387+ expect ( hasNestedSqlHighlighting ) . toBe ( true ) ;
388+ } ) ;
264389} ) ;
0 commit comments