@@ -235,4 +235,111 @@ test("Unterminated string", () => {
235
235
expect ( e ) . toBeInstanceOf ( UnterminatedStringError ) ;
236
236
console . log ( e . message ) ;
237
237
}
238
- } )
238
+ } )
239
+
240
+ describe ( "Triple quote string with nested quotes" , ( ) => {
241
+ const reference_location = new CodeLocation ( {
242
+ screen_name : "test" ,
243
+ line : 1 ,
244
+ column : 1 ,
245
+ start_pos : 0 ,
246
+ } ) ;
247
+
248
+ test ( "Basic case: '''I said 'Hello''''" , ( ) => {
249
+ const input = "'''I said 'Hello''''" ;
250
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
251
+ const token = tokenizer . next_token ( ) ;
252
+
253
+ expect ( token . string ) . toEqual ( "I said 'Hello'" ) ;
254
+ } ) ;
255
+
256
+ test ( "Normal triple quote behavior (no 4+ consecutive quotes)" , ( ) => {
257
+ const input = "'''Hello'''" ;
258
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
259
+ const token = tokenizer . next_token ( ) ;
260
+
261
+ expect ( token . string ) . toEqual ( "Hello" ) ;
262
+ } ) ;
263
+
264
+ test ( "Double quotes with greedy mode" , ( ) => {
265
+ const input = '"""I said "Hello""""' ;
266
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
267
+ const token = tokenizer . next_token ( ) ;
268
+
269
+ expect ( token . string ) . toEqual ( 'I said "Hello"' ) ;
270
+ } ) ;
271
+
272
+ test ( "Six consecutive quotes (empty string case)" , ( ) => {
273
+ const input = "''''''" ;
274
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
275
+ const token = tokenizer . next_token ( ) ;
276
+
277
+ expect ( token . string ) . toEqual ( "" ) ;
278
+ } ) ;
279
+
280
+ test ( "Eight consecutive quotes (two quote content)" , ( ) => {
281
+ const input = "''''''''" ;
282
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
283
+ const token = tokenizer . next_token ( ) ;
284
+
285
+ expect ( token . string ) . toEqual ( "''" ) ;
286
+ } ) ;
287
+
288
+ test ( "Multiple nested quotes" , ( ) => {
289
+ const input = `"""He said "I said 'Hello' to you""""` ;
290
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
291
+ const token = tokenizer . next_token ( ) ;
292
+
293
+ expect ( token . string ) . toEqual ( `He said "I said 'Hello' to you"` ) ;
294
+ } ) ;
295
+
296
+ test ( "No greedy mode when triple quote not followed by quote" , ( ) => {
297
+ const input = "'''Hello''' world'''" ;
298
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
299
+ const token = tokenizer . next_token ( ) ;
300
+
301
+ // Should close at first ''' since it's not followed by another quote
302
+ expect ( token . string ) . toEqual ( "Hello" ) ;
303
+ } ) ;
304
+
305
+ test ( "Content with apostrophes (contractions)" , ( ) => {
306
+ const input = "'''It's a beautiful day, isn't it?''''" ;
307
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
308
+ const token = tokenizer . next_token ( ) ;
309
+
310
+ expect ( token . string ) . toEqual ( "It's a beautiful day, isn't it?'" ) ;
311
+ } ) ;
312
+
313
+ test ( "Mixed quote types don't trigger greedy mode" , ( ) => {
314
+ const input = "'''Hello\"\"\"" ;
315
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
316
+
317
+ try {
318
+ tokenizer . next_token ( ) ;
319
+ } catch ( e ) {
320
+ expect ( e ) . toBeInstanceOf ( UnterminatedStringError ) ;
321
+ }
322
+ } ) ;
323
+
324
+ test ( "Backward compatibility: normal strings unchanged" , ( ) => {
325
+ const inputs = [
326
+ "'''simple'''" ,
327
+ "'''multi\nline\nstring'''" ,
328
+ "'''string with \"double quotes\"'''" ,
329
+ "'''string with 'single quotes'''''"
330
+ ] ;
331
+
332
+ const expected = [
333
+ "simple" ,
334
+ "multi\nline\nstring" ,
335
+ 'string with "double quotes"' ,
336
+ "string with 'single quotes''"
337
+ ] ;
338
+
339
+ inputs . forEach ( ( input , i ) => {
340
+ const tokenizer = new Tokenizer ( input , reference_location ) ;
341
+ const token = tokenizer . next_token ( ) ;
342
+ expect ( token . string ) . toEqual ( expected [ i ] ) ;
343
+ } ) ;
344
+ } ) ;
345
+ } ) ;
0 commit comments