@@ -607,13 +607,15 @@ let RuleKeyword_ParseBlocks () =
607607 Assert.AreEqual( 1 , secondRule.Scenarios.Length) // One scenario in second rule
608608
609609[<Test>]
610- let EscapedPipe_ParseLines () =
610+ let EscapedCharacters_ParseLines () =
611611 " TickSpec.Tests.EscapedPipe.feature"
612612 |> loadFeatureFile
613613 |> verifyLineParsing <|
614614 [
615615 FileStart
616- FeatureName " Escaped pipe in table cells"
616+ FeatureName " Escaped characters in table cells"
617+
618+ // Scenario Outline: escaped pipes
617619 Scenario " Scenario Outline: Values with escaped pipes are parsed correctly"
618620 Step ( GivenStep " a value <value>" )
619621 Step ( ThenStep " the value is <expected>" )
@@ -624,6 +626,24 @@ let EscapedPipe_ParseLines () =
624626 Item ( Examples, TableRow [ " |leading" ; " |leading" ])
625627 Item ( Examples, TableRow [ " trailing|" ; " trailing|" ])
626628 Item ( Examples, TableRow [ " a|b|c" ; " a|b|c" ])
629+
630+ // Scenario Outline: escaped backslashes
631+ Scenario " Scenario Outline: Values with escaped backslashes are parsed correctly"
632+ Step ( GivenStep " a value <value>" )
633+ Step ( ThenStep " the value is <expected>" )
634+ Examples
635+ Item ( Examples, TableRow [ " value" ; " expected" ])
636+ Item ( Examples, TableRow [ " hello\\ world" ; " hello\\ world" ])
637+
638+ // Scenario Outline: escaped newlines
639+ Scenario " Scenario Outline: Values with escaped newlines are parsed correctly"
640+ Step ( GivenStep " a value <value>" )
641+ Step ( ThenStep " the value is <expected>" )
642+ Examples
643+ Item ( Examples, TableRow [ " value" ; " expected" ])
644+ Item ( Examples, TableRow [ " line1\n line2" ; " line1\n line2" ])
645+
646+ // Scenario: step table with escaped pipes
627647 Scenario " Scenario: Step table with escaped pipes"
628648 Step ( GivenStep " a table with escaped pipes" )
629649 Item ( Step ( GivenStep " a table with escaped pipes" ), TableRow [ " col1" ; " col2" ])
@@ -632,20 +652,51 @@ let EscapedPipe_ParseLines () =
632652 Step ( ThenStep " the table cell 0,0 is hello|world" )
633653 Step ( ThenStep " the table cell 0,1 is normal" )
634654 Step ( ThenStep " the table cell 1,0 is a|b|c" )
655+
656+ // Scenario: step table with escaped backslashes
657+ Scenario " Scenario: Step table with escaped backslashes"
658+ Step ( GivenStep " a table with escaped backslashes" )
659+ Item ( Step ( GivenStep " a table with escaped backslashes" ), TableRow [ " col1" ; " col2" ])
660+ Item ( Step ( GivenStep " a table with escaped backslashes" ), TableRow [ " hello\\ world" ; " normal" ])
661+ Step ( ThenStep " the table cell 0,0 is hello\\ world" )
662+ Step ( ThenStep " the table cell 0,1 is normal" )
663+
664+ // Scenario: escaped backslash before pipe acts as delimiter
665+ Scenario " Scenario: Escaped backslash before pipe acts as cell delimiter"
666+ Step ( GivenStep " a table with escaped backslash before pipe" )
667+ Item ( Step ( GivenStep " a table with escaped backslash before pipe" ), TableRow [ " col1" ; " col2" ; " col3" ])
668+ Item ( Step ( GivenStep " a table with escaped backslash before pipe" ), TableRow [ " before\\ " ; " after" ; " end" ])
669+ Step ( ThenStep " the table cell 0,0 is before\\ " )
670+ Step ( ThenStep " the table cell 0,1 is after" )
671+ Step ( ThenStep " the table cell 0,2 is end" )
672+
673+ // Scenario: triple backslash-pipe (\\\| -> \|)
674+ Scenario " Scenario: Triple backslash-pipe is escaped backslash then escaped pipe"
675+ Step ( GivenStep " a table with triple backslash-pipe" )
676+ Item ( Step ( GivenStep " a table with triple backslash-pipe" ), TableRow [ " col1" ; " col2" ])
677+ Item ( Step ( GivenStep " a table with triple backslash-pipe" ), TableRow [ " a\\ |b" ; " normal" ])
678+ Step ( ThenStep " the table cell 0,0 is a\\ |b" )
679+ Step ( ThenStep " the table cell 0,1 is normal" )
680+
681+ // Scenario: escaped backslash before n (\\n -> \n literal, not newline)
682+ Scenario " Scenario: Escaped backslash before n is literal backslash-n not newline"
683+ Step ( GivenStep " a table with escaped backslash before n" )
684+ Item ( Step ( GivenStep " a table with escaped backslash before n" ), TableRow [ " col1" ; " col2" ])
685+ Item ( Step ( GivenStep " a table with escaped backslash before n" ), TableRow [ " test\\ n" ; " normal" ])
686+ Step ( ThenStep " the table cell 0,0 is test\\ n" )
687+ Step ( ThenStep " the table cell 0,1 is normal" )
635688 ]
636689
637690[<Test>]
638- let EscapedPipe_ParseFeature () =
691+ let EscapedCharacters_ParseFeature () =
639692 let featureSource =
640693 " TickSpec.Tests.EscapedPipe.feature"
641694 |> loadFeatureFile
642695 |> FeatureParser.parseFeature
643696
644- Assert.AreEqual( " Escaped pipe in table cells" , featureSource.Name)
645- Assert.AreEqual( 6 , featureSource.Scenarios.Length)
697+ Assert.AreEqual( " Escaped characters in table cells" , featureSource.Name)
646698
647- // Verify the outline scenarios with escaped pipes produce correct parameter values
648- // Row order: 0=no pipe, 1=before|after, 2=|leading, 3=trailing|, 4=a|b|c
699+ // Outline 1: escaped pipes (5 data rows -> scenarios 0-4)
649700 let scenario1 = featureSource.Scenarios.[ 1 ]
650701 let params1 = scenario1.Parameters |> dict
651702 Assert.AreEqual( " before|after" , params1.[ " value" ])
@@ -656,12 +707,48 @@ let EscapedPipe_ParseFeature () =
656707 Assert.AreEqual( " a|b|c" , params4.[ " value" ])
657708 Assert.AreEqual( " a|b|c" , params4.[ " expected" ])
658709
659- // Verify step table with escaped pipes
660- let tableScenario = featureSource.Scenarios.[ 5 ]
661- let tableStep = tableScenario.Steps.[ 0 ] |> fst
662- Assert.AreEqual( GivenStep " a table with escaped pipes" , tableStep)
663- let table = ( tableScenario.Steps.[ 0 ] |> snd) .Table.Value
664- Assert.AreEqual([| " col1" ; " col2" |], table.Header)
665- Assert.AreEqual( " hello|world" , table.Rows.[ 0 ].[ 0 ])
666- Assert.AreEqual( " normal" , table.Rows.[ 0 ].[ 1 ])
667- Assert.AreEqual( " a|b|c" , table.Rows.[ 1 ].[ 0 ])
710+ // Outline 2: escaped backslashes (1 data row -> scenario 5)
711+ let bsScenario = featureSource.Scenarios.[ 5 ]
712+ let bsParams = bsScenario.Parameters |> dict
713+ Assert.AreEqual( " hello\\ world" , bsParams.[ " value" ])
714+ Assert.AreEqual( " hello\\ world" , bsParams.[ " expected" ])
715+
716+ // Outline 3: escaped newlines (1 data row -> scenario 6)
717+ let nlScenario = featureSource.Scenarios.[ 6 ]
718+ let nlParams = nlScenario.Parameters |> dict
719+ Assert.AreEqual( " line1\n line2" , nlParams.[ " value" ])
720+ Assert.AreEqual( " line1\n line2" , nlParams.[ " expected" ])
721+
722+ // Scenario: step table with escaped pipes (scenario 7)
723+ let pipeTableScenario = featureSource.Scenarios.[ 7 ]
724+ let pipeTable = ( pipeTableScenario.Steps.[ 0 ] |> snd) .Table.Value
725+ Assert.AreEqual([| " col1" ; " col2" |], pipeTable.Header)
726+ Assert.AreEqual( " hello|world" , pipeTable.Rows.[ 0 ].[ 0 ])
727+ Assert.AreEqual( " normal" , pipeTable.Rows.[ 0 ].[ 1 ])
728+ Assert.AreEqual( " a|b|c" , pipeTable.Rows.[ 1 ].[ 0 ])
729+
730+ // Scenario: step table with escaped backslashes (scenario 8)
731+ let bsTableScenario = featureSource.Scenarios.[ 8 ]
732+ let bsTable = ( bsTableScenario.Steps.[ 0 ] |> snd) .Table.Value
733+ Assert.AreEqual( " hello\\ world" , bsTable.Rows.[ 0 ].[ 0 ])
734+ Assert.AreEqual( " normal" , bsTable.Rows.[ 0 ].[ 1 ])
735+
736+ // Scenario: escaped backslash before pipe = cell delimiter (scenario 9)
737+ let delimScenario = featureSource.Scenarios.[ 9 ]
738+ let delimTable = ( delimScenario.Steps.[ 0 ] |> snd) .Table.Value
739+ Assert.AreEqual([| " col1" ; " col2" ; " col3" |], delimTable.Header)
740+ Assert.AreEqual( " before\\ " , delimTable.Rows.[ 0 ].[ 0 ])
741+ Assert.AreEqual( " after" , delimTable.Rows.[ 0 ].[ 1 ])
742+ Assert.AreEqual( " end" , delimTable.Rows.[ 0 ].[ 2 ])
743+
744+ // Scenario: triple backslash-pipe \\\| -> \| (scenario 10)
745+ let tripleScenario = featureSource.Scenarios.[ 10 ]
746+ let tripleTable = ( tripleScenario.Steps.[ 0 ] |> snd) .Table.Value
747+ Assert.AreEqual( " a\\ |b" , tripleTable.Rows.[ 0 ].[ 0 ])
748+ Assert.AreEqual( " normal" , tripleTable.Rows.[ 0 ].[ 1 ])
749+
750+ // Scenario: \\n -> literal \n, not newline (scenario 11)
751+ let bsNScenario = featureSource.Scenarios.[ 11 ]
752+ let bsNTable = ( bsNScenario.Steps.[ 0 ] |> snd) .Table.Value
753+ Assert.AreEqual( " test\\ n" , bsNTable.Rows.[ 0 ].[ 0 ])
754+ Assert.IsFalse( bsNTable.Rows.[ 0 ].[ 0 ]. Contains( " \n " ), " Should not contain actual newline" )
0 commit comments