@@ -20,8 +20,10 @@ import {
2020 toggleInlineFormat ,
2121 selectRangeOfWordAtCaret ,
2222 formatRange ,
23+ formatRangeAsCode ,
2324} from "../../src/editor/operations" ;
2425import { Formatting } from "../../src/components/views/rooms/MessageComposerFormatBar" ;
26+ import { longestBacktickSequence } from '../../src/editor/deserialize' ;
2527
2628const SERIALIZED_NEWLINE = { "text" : "\n" , "type" : "newline" } ;
2729
@@ -43,6 +45,89 @@ describe('editor/operations: formatting operations', () => {
4345 expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "hello _world_!" , "type" : "plain" } ] ) ;
4446 } ) ;
4547
48+ describe ( 'escape backticks' , ( ) => {
49+ it ( 'works for escaping backticks in between texts' , ( ) => {
50+ const renderer = createRenderer ( ) ;
51+ const pc = createPartCreator ( ) ;
52+ const model = new EditorModel ( [
53+ pc . plain ( "hello ` world!" ) ,
54+ ] , pc , renderer ) ;
55+
56+ const range = model . startRange ( model . positionForOffset ( 0 , false ) ,
57+ model . positionForOffset ( 13 , false ) ) ; // hello ` world
58+
59+ expect ( range . parts [ 0 ] . text . trim ( ) . includes ( "`" ) ) . toBeTruthy ( ) ;
60+ expect ( longestBacktickSequence ( range . parts [ 0 ] . text . trim ( ) ) ) . toBe ( 1 ) ;
61+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "hello ` world!" , "type" : "plain" } ] ) ;
62+ formatRangeAsCode ( range ) ;
63+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "``hello ` world``!" , "type" : "plain" } ] ) ;
64+ } ) ;
65+
66+ it ( 'escapes longer backticks in between text' , ( ) => {
67+ const renderer = createRenderer ( ) ;
68+ const pc = createPartCreator ( ) ;
69+ const model = new EditorModel ( [
70+ pc . plain ( "hello```world" ) ,
71+ ] , pc , renderer ) ;
72+
73+ const range = model . startRange ( model . positionForOffset ( 0 , false ) ,
74+ model . getPositionAtEnd ( ) ) ; // hello```world
75+
76+ expect ( range . parts [ 0 ] . text . includes ( "`" ) ) . toBeTruthy ( ) ;
77+ expect ( longestBacktickSequence ( range . parts [ 0 ] . text ) ) . toBe ( 3 ) ;
78+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "hello```world" , "type" : "plain" } ] ) ;
79+ formatRangeAsCode ( range ) ;
80+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "````hello```world````" , "type" : "plain" } ] ) ;
81+ } ) ;
82+
83+ it ( 'escapes non-consecutive with varying length backticks in between text' , ( ) => {
84+ const renderer = createRenderer ( ) ;
85+ const pc = createPartCreator ( ) ;
86+ const model = new EditorModel ( [
87+ pc . plain ( "hell```o`w`o``rld" ) ,
88+ ] , pc , renderer ) ;
89+
90+ const range = model . startRange ( model . positionForOffset ( 0 , false ) ,
91+ model . getPositionAtEnd ( ) ) ; // hell```o`w`o``rld
92+ expect ( range . parts [ 0 ] . text . includes ( "`" ) ) . toBeTruthy ( ) ;
93+ expect ( longestBacktickSequence ( range . parts [ 0 ] . text ) ) . toBe ( 3 ) ;
94+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "hell```o`w`o``rld" , "type" : "plain" } ] ) ;
95+ formatRangeAsCode ( range ) ;
96+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "````hell```o`w`o``rld````" , "type" : "plain" } ] ) ;
97+ } ) ;
98+
99+ it ( 'untoggles correctly if its already formatted' , ( ) => {
100+ const renderer = createRenderer ( ) ;
101+ const pc = createPartCreator ( ) ;
102+ const model = new EditorModel ( [
103+ pc . plain ( "```hello``world```" ) ,
104+ ] , pc , renderer ) ;
105+
106+ const range = model . startRange ( model . positionForOffset ( 0 , false ) ,
107+ model . getPositionAtEnd ( ) ) ; // hello``world
108+ expect ( range . parts [ 0 ] . text . includes ( "`" ) ) . toBeTruthy ( ) ;
109+ expect ( longestBacktickSequence ( range . parts [ 0 ] . text ) ) . toBe ( 3 ) ;
110+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "```hello``world```" , "type" : "plain" } ] ) ;
111+ formatRangeAsCode ( range ) ;
112+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "hello``world" , "type" : "plain" } ] ) ;
113+ } ) ;
114+ it ( 'untoggles correctly it contains varying length of backticks between text' , ( ) => {
115+ const renderer = createRenderer ( ) ;
116+ const pc = createPartCreator ( ) ;
117+ const model = new EditorModel ( [
118+ pc . plain ( "````hell```o`w`o``rld````" ) ,
119+ ] , pc , renderer ) ;
120+
121+ const range = model . startRange ( model . positionForOffset ( 0 , false ) ,
122+ model . getPositionAtEnd ( ) ) ; // hell```o`w`o``rld
123+ expect ( range . parts [ 0 ] . text . includes ( "`" ) ) . toBeTruthy ( ) ;
124+ expect ( longestBacktickSequence ( range . parts [ 0 ] . text ) ) . toBe ( 4 ) ;
125+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "````hell```o`w`o``rld````" , "type" : "plain" } ] ) ;
126+ formatRangeAsCode ( range ) ;
127+ expect ( model . serializeParts ( ) ) . toEqual ( [ { "text" : "hell```o`w`o``rld" , "type" : "plain" } ] ) ;
128+ } ) ;
129+ } ) ;
130+
46131 it ( 'works for parts of words' , ( ) => {
47132 const renderer = createRenderer ( ) ;
48133 const pc = createPartCreator ( ) ;
0 commit comments